[edk2-libc Patch 1/1] AppPkg/Applications/Python/Python-3.6.8: Py 3.6.8 UEFI changes


Michael D Kinney
 

From: Jayaprakash Nevara <n.jayaprakash@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3588

This commit contains several changes made to the base Python 3.6.8
source code to compile it and run it on UEFI shell.
Currently supports building Py3.6.8 for UEFI with IA32 and X64
architectures using VS2017, VS2019 with the latest edk2/master.

Cc: Rebecca Cran <rebecca@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Jayaprakash N <n.jayaprakash@intel.com>
---
AppPkg/AppPkg.dsc | 3 +
.../Python/Python-3.6.8/Py368ReadMe.txt | 220 +
.../PyMod-3.6.8/Include/fileutils.h | 159 +
.../Python-3.6.8/PyMod-3.6.8/Include/osdefs.h | 51 +
.../PyMod-3.6.8/Include/pyconfig.h | 1322 ++
.../PyMod-3.6.8/Include/pydtrace.h | 74 +
.../Python-3.6.8/PyMod-3.6.8/Include/pyport.h | 788 +
.../PyMod-3.6.8/Lib/ctypes/__init__.py | 549 +
.../PyMod-3.6.8/Lib/genericpath.py | 157 +
.../Python-3.6.8/PyMod-3.6.8/Lib/glob.py | 110 +
.../PyMod-3.6.8/Lib/http/client.py | 1481 ++
.../Lib/importlib/_bootstrap_external.py | 1443 ++
.../Python/Python-3.6.8/PyMod-3.6.8/Lib/io.py | 99 +
.../PyMod-3.6.8/Lib/logging/__init__.py | 2021 ++
.../Python-3.6.8/PyMod-3.6.8/Lib/ntpath.py | 568 +
.../Python/Python-3.6.8/PyMod-3.6.8/Lib/os.py | 792 +
.../Python-3.6.8/PyMod-3.6.8/Lib/pydoc.py | 2686 +++
.../Python-3.6.8/PyMod-3.6.8/Lib/shutil.py | 1160 ++
.../Python-3.6.8/PyMod-3.6.8/Lib/site.py | 529 +
.../PyMod-3.6.8/Lib/subprocess.py | 1620 ++
.../Python-3.6.8/PyMod-3.6.8/Lib/zipfile.py | 2060 ++
.../PyMod-3.6.8/Modules/_blake2/impl/blake2.h | 161 +
.../PyMod-3.6.8/Modules/_ctypes/_ctypes.c | 5623 ++++++
.../PyMod-3.6.8/Modules/_ctypes/callproc.c | 1871 ++
.../Modules/_ctypes/ctypes_dlfcn.h | 29 +
.../Modules/_ctypes/libffi_msvc/ffi.c | 572 +
.../Modules/_ctypes/libffi_msvc/ffi.h | 331 +
.../Modules/_ctypes/libffi_msvc/ffi_common.h | 85 +
.../Modules/_ctypes/malloc_closure.c | 128 +
.../Python-3.6.8/PyMod-3.6.8/Modules/config.c | 159 +
.../PyMod-3.6.8/Modules/edk2module.c | 4348 +++++
.../PyMod-3.6.8/Modules/errnomodule.c | 890 +
.../PyMod-3.6.8/Modules/faulthandler.c | 1414 ++
.../PyMod-3.6.8/Modules/getpath.c | 1283 ++
.../Python-3.6.8/PyMod-3.6.8/Modules/main.c | 878 +
.../PyMod-3.6.8/Modules/selectmodule.c | 2638 +++
.../PyMod-3.6.8/Modules/socketmodule.c | 7810 ++++++++
.../PyMod-3.6.8/Modules/socketmodule.h | 282 +
.../PyMod-3.6.8/Modules/sre_lib.h | 1372 ++
.../PyMod-3.6.8/Modules/timemodule.c | 1526 ++
.../PyMod-3.6.8/Modules/zlib/gzguts.h | 218 +
.../PyMod-3.6.8/Objects/dictobject.c | 4472 +++++
.../PyMod-3.6.8/Objects/memoryobject.c | 3114 +++
.../Python-3.6.8/PyMod-3.6.8/Objects/object.c | 2082 ++
.../Objects/stringlib/transmogrify.h | 701 +
.../PyMod-3.6.8/Objects/unicodeobject.c | 15773 ++++++++++++++++
.../PyMod-3.6.8/Python/bltinmodule.c | 2794 +++
.../PyMod-3.6.8/Python/fileutils.c | 1767 ++
.../PyMod-3.6.8/Python/getcopyright.c | 38 +
.../PyMod-3.6.8/Python/importlib_external.h | 2431 +++
.../Python-3.6.8/PyMod-3.6.8/Python/marshal.c | 1861 ++
.../Python-3.6.8/PyMod-3.6.8/Python/pyhash.c | 437 +
.../PyMod-3.6.8/Python/pylifecycle.c | 1726 ++
.../Python-3.6.8/PyMod-3.6.8/Python/pystate.c | 969 +
.../Python-3.6.8/PyMod-3.6.8/Python/pytime.c | 749 +
.../Python-3.6.8/PyMod-3.6.8/Python/random.c | 636 +
.../Python/Python-3.6.8/Python368.inf | 275 +
.../Python-3.6.8/create_python368_pkg.bat | 48 +
.../Python/Python-3.6.8/srcprep.py | 30 +
59 files changed, 89413 insertions(+)
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/Py368ReadMe.txt
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/fileutils.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/osdefs.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyconfig.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pydtrace.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyport.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ctypes/__init__.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/genericpath.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/glob.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/http/client.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/importlib/_bootstrap_external.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/io.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/logging/__init__.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ntpath.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/os.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/pydoc.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/shutil.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/site.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/subprocess.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/zipfile.py
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_blake2/impl/blake2.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/_ctypes.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/callproc.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/ctypes_dlfcn.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/libffi_msvc/ffi.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/libffi_msvc/ffi.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/libffi_msvc/ffi_common.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/_ctypes/malloc_closure.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/config.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/edk2module.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/errnomodule.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/faulthandler.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/getpath.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/main.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/selectmodule.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/socketmodule.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/socketmodule.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/sre_lib.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/timemodule.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Modules/zlib/gzguts.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Objects/dictobject.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Objects/memoryobject.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Objects/object.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Objects/stringlib/transmogrify.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Objects/unicodeobject.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/bltinmodule.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/fileutils.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/getcopyright.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/importlib_external.h
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/marshal.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/pyhash.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/pylifecycle.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/pystate.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/pytime.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Python/random.c
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/Python368.inf
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/create_python368_pkg.bat
create mode 100644 AppPkg/Applications/Python/Python-3.6.8/srcprep.py

diff --git a/AppPkg/AppPkg.dsc b/AppPkg/AppPkg.dsc
index c2305d71..5938789d 100644
--- a/AppPkg/AppPkg.dsc
+++ b/AppPkg/AppPkg.dsc
@@ -126,6 +126,9 @@
#### Un-comment the following line to build Python 2.7.10.
# AppPkg/Applications/Python/Python-2.7.10/Python2710.inf

+#### Un-comment the following line to build Python 3.6.8.
+# AppPkg/Applications/Python/Python-3.6.8/Python368.inf
+
#### Un-comment the following line to build Lua.
# AppPkg/Applications/Lua/Lua.inf

diff --git a/AppPkg/Applications/Python/Python-3.6.8/Py368ReadMe.txt b/AppPkg/Applications/Python/Python-3.6.8/Py368ReadMe.txt
new file mode 100644
index 00000000..69bb6bd1
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/Py368ReadMe.txt
@@ -0,0 +1,220 @@
+ EDK II Python
+ ReadMe
+ Version 3.6.8
+ Release 1.00
+ 01 September 2021
+
+
+1. OVERVIEW
+===========
+This document is devoted to general information on building and setup of the
+Python environment for UEFI, the invocation of the interpreter, and things
+that make working with Python easier.
+
+It is assumed that you already have UDK2018 or later, or a current snapshot of
+the EDK II sources from www.tianocore.org (https://github.com/tianocore/edk2),
+and that you can successfully build packages within that distribution.
+
+2. Release Notes
+================
+ 1) All C extension modules must be statically linked (built in)
+ 2) The site and os modules must exist as discrete files in ...\lib\python36.8
+ 3) User-specific configurations are not supported.
+ 4) Environment variables are not supported.
+
+3. Getting and Building Python
+======================================================
+ 3.1 Getting Python
+ ==================
+ This file describes the UEFI port of version 3.6.8 of the CPython distribution.
+ For development ease, a subset of the Python 3.6.8 distribution has been
+ included as part of the AppPkg/Applications/Python/Python-3.6.8 source tree.
+ If this is sufficient, you may skip to section 3.2, Building Python.
+
+ If a full distribution is desired, it can be merged into the Python-3.6.8
+ source tree. Directory AppPkg/Applications/Python/Python-3.6.8 corresponds
+ to the root directory of the CPython 3.6.8 distribution. The full
+ CPython 3.6.8 source code may be downloaded from
+ http://www.python.org/ftp/python/3.6.8/.
+
+ A. Within your EDK II development tree, extract the Python distribution into
+ AppPkg/Applications/Python/Python-3.6.8. This should merge the additional
+ files into the source tree. It will also create the following directories:
+ Demo Doc Grammar Mac Misc
+ PC PCbuild RISCOS Tools
+
+ The greatest change will be within the Python-3.6.8/Lib directory where
+ many more packages and modules will be added. These additional components
+ may not have been ported to EDK II yet.
+
+ 3.2 Building Python
+ ===================
+ A. From the AppPkg/Applications/Python/Python-3.6.8 directory, execute the
+ srcprep.py script to copy the header files from within the
+ PyMod-3.6.8 sub-tree into their corresponding directories within the
+ distribution. This step only needs to be performed prior to the first
+ build of Python, or if one of the header files within the PyMod tree has been
+ modified.
+
+ B. Edit PyMod-3.6.8\Modules\config.c to enable the built-in modules you need.
+ By default, it is configured for the minimally required set of modules.
+ Mandatory Built-in Modules:
+ edk2 errno imp marshal
+
+ Additional built-in modules which are required to use the help()
+ functionality provided by PyDoc, are:
+ _codecs _collections _functools _random
+ _sre _struct _weakref binascii
+ gc itertools math _operator
+ time
+
+ C. Edit AppPkg/AppPkg.dsc to enable (uncomment) the Python368.inf line
+ within the [Components] section.
+
+ D. Build AppPkg using the standard "build" command:
+ For example, to build Python for an X64 CPU architecture:
+ build -a X64 -p AppPkg\AppPkg.dsc
+
+4. Python-related paths and files
+=================================
+Python depends upon the existence of several directories and files on the
+target system.
+
+ \EFI Root of the UEFI system area.
+ |- \Tools Location of the Python.efi executable.
+ |- \Boot UEFI specified Boot directory.
+ |- \StdLib Root of the Standard Libraries sub-tree.
+ |- \etc Configuration files used by libraries.
+ |- \lib Root of the libraries tree.
+ |- \python36.8 Directory containing the Python library
+ | modules.
+ |- \lib-dynload Dynamically loadable Python extensions.
+ | Not supported currently.
+ |- \site-packages Site-specific packages and modules.
+
+
+5. Installing Python
+====================
+These directories, on the target system, are populated from the development
+system as follows:
+
+ * \Efi\Tools receives a copy of Build/AppPkg/RELEASE_VS2017/X64/Python368.efi.
+ ^^^^^^^^^^^^^^^^
+ Modify the host path to match your build type and compiler.
+
+ * The \Efi\StdLib\etc directory is populated from the StdLib/Efi/StdLib/etc
+ source directory.
+
+ * Directory \Efi\StdLib\lib\python36.8 is populated with packages and modules
+ from the AppPkg/Applications/Python/Python-3.6.8/Lib directory.
+ The recommended minimum set of modules (.py, .pyc, and/or .pyo):
+ os stat ntpath warnings traceback
+ site types linecache genericpath
+
+ * Python C Extension Modules built as dynamically loadable extensions go into
+ the \Efi\StdLib\lib\python36.8\lib-dynload directory. This functionality is not
+ yet implemented.
+
+ A script, create_python368_pkg.bat , is provided which facilitates the population
+ of the target EFI package. Execute this script from within the
+ AppPkg/Applications/Python/Python-3.6.8 directory, providing the Tool Chain, Target
+ Build and destination directory which is the path to the destination directory.
+ The appropriate contents of the AppPkg/Applications/Python/Python-3.6.8/Lib and
+ Python368.efi Application from Build/AppPkg/RELEASE_VS2017/X64/ will be
+ ^^^^^^^^^^^^^^
+ copied into the specified destination directory.
+
+ Replace "RELEASE_VS2017", in the source path, with values appropriate for your tool chain.
+
+
+6. Example: Enabling socket support
+===================================
+ 1. enable {"_socket", init_socket}, in PyMod-3.6.8\Modules\config.c
+ 2. enable LibraryClasses BsdSocketLib and EfiSocketLib in Python368.inf.
+ 3. Build Python368
+ build -a X64 -p AppPkg\AppPkg.dsc
+ 6. copy Build\AppPkg\RELEASE_VS2017\X64\Python368.efi to \Efi\Tools on your
+ target system. Replace "RELEASE_VS2017", in the source path, with
+ values appropriate for your tool chain.
+
+7. Running Python
+=================
+ Python must currently be run from an EFI FAT-32 partition, or volume, under
+ the UEFI Shell. At the Shell prompt enter the desired volume name, followed
+ by a colon ':', then press Enter. Python can then be executed by typing its
+ name, followed by any desired options and arguments.
+
+ EXAMPLE:
+ Shell> fs0:
+ FS0:\> python368
+ Python 3.6.8 (default, Jun 24 2015, 17:38:32) [C] on uefi
+ Type "help", "copyright", "credits" or "license" for more information.
+ >>> exit()
+ FS0:\>
+
+
+8. Supported C Modules
+======================
+ Module Name C File(s)
+ =============== =============================================
+ _ast Python/Python-ast.c
+ _codecs Modules/_codecsmodule.c
+ _collections Modules/_collectionsmodule.c
+ _csv Modules/_csv.c
+ _functools Modules/_functoolsmodule.c
+ _io Modules/_io/_iomodule.c
+ _json Modules/_json.c
+ _md5 Modules/md5module.c
+ _multibytecodec Modules/cjkcodecs/multibytecodec.c
+ _random Modules/_randommodule.c
+ _sha1 Modules/sha1module.c
+ _sha256 Modules/sha256module.c
+ _sha512 Modules/sha512module.c
+ _sre Modules/_sre.c
+ _struct Modules/_struct.c
+ _symtable Modules/symtablemodule.c
+ _weakref Modules/_weakref.c
+ array Modules/arraymodule.c
+ binascii Modules/binascii.c
+ cmath Modules/cmathmodule.c
+ datetime Modules/_datetimemodule.c
+ edk2 Modules/PyMod-3.6.8/edk2module.c
+ errno Modules/errnomodule.c
+ gc Modules/gcmodule.c
+ imp Python/import.c
+ itertools Modules/itertoolsmodule.c
+ marshal Python/marshal.c
+ _operator Modules/_operator.c
+ parser Modules/parsermodule.c
+ select Modules/selectmodule.c
+ signal Modules/signalmodule.c
+ time Modules/timemodule.c
+ zlib Modules/zlibmodule.c
+
+
+9. Tested Python Library Modules
+================================
+This is a partial list of the packages and modules of the Python Standard
+Library that have been tested or used in some manner.
+
+ encodings genericpath.py site.py
+ importlib getopt.py socket.py
+ json hashlib.py sre.py
+ pydoc_data heapq.py sre_compile.py
+ xml inspect.py sre_constants.py
+ abc.py io.py sre_parse.py
+ argparse.py keyword.py stat.py
+ ast.py linecache.py string.py
+ atexit.py locale.py struct.py
+ binhex.py modulefinder.py textwrap.py
+ bisect.py ntpath.py token.py
+ calendar.py numbers.py tokenize.py
+ cmd.py optparse.py traceback.py
+ codecs.py os.py types.py
+ collections.py platform.py warnings.py
+ copy.py posixpath.py weakref.py
+ csv.py pydoc.py zipfile.py
+ fileinput.py random.py
+ formatter.py re.py
+ functools.py runpy.py
+# # #
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/fileutils.h b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/fileutils.h
new file mode 100644
index 00000000..5540505d
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/fileutils.h
@@ -0,0 +1,159 @@
+#ifndef Py_FILEUTILS_H
+#define Py_FILEUTILS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03050000
+PyAPI_FUNC(wchar_t *) Py_DecodeLocale(
+ const char *arg,
+ size_t *size);
+
+PyAPI_FUNC(char*) Py_EncodeLocale(
+ const wchar_t *text,
+ size_t *error_pos);
+#endif
+
+#ifndef Py_LIMITED_API
+
+PyAPI_FUNC(wchar_t *) _Py_DecodeLocaleEx(
+ const char *arg,
+ size_t *size,
+ int current_locale);
+
+PyAPI_FUNC(char*) _Py_EncodeLocaleEx(
+ const wchar_t *text,
+ size_t *error_pos,
+ int current_locale);
+
+PyAPI_FUNC(PyObject *) _Py_device_encoding(int);
+
+#if defined(MS_WINDOWS) || defined(__APPLE__) || defined(UEFI_C_SOURCE)
+ /* On Windows, the count parameter of read() is an int (bpo-9015, bpo-9611).
+ On macOS 10.13, read() and write() with more than INT_MAX bytes
+ fail with EINVAL (bpo-24658). */
+# define _PY_READ_MAX INT_MAX
+# define _PY_WRITE_MAX INT_MAX
+#else
+ /* write() should truncate the input to PY_SSIZE_T_MAX bytes,
+ but it's safer to do it ourself to have a portable behaviour */
+# define _PY_READ_MAX PY_SSIZE_T_MAX
+# define _PY_WRITE_MAX PY_SSIZE_T_MAX
+#endif
+
+#ifdef MS_WINDOWS
+struct _Py_stat_struct {
+ unsigned long st_dev;
+ uint64_t st_ino;
+ unsigned short st_mode;
+ int st_nlink;
+ int st_uid;
+ int st_gid;
+ unsigned long st_rdev;
+ __int64 st_size;
+ time_t st_atime;
+ int st_atime_nsec;
+ time_t st_mtime;
+ int st_mtime_nsec;
+ time_t st_ctime;
+ int st_ctime_nsec;
+ unsigned long st_file_attributes;
+};
+#else
+# define _Py_stat_struct stat
+#endif
+
+PyAPI_FUNC(int) _Py_fstat(
+ int fd,
+ struct _Py_stat_struct *status);
+
+PyAPI_FUNC(int) _Py_fstat_noraise(
+ int fd,
+ struct _Py_stat_struct *status);
+
+PyAPI_FUNC(int) _Py_stat(
+ PyObject *path,
+ struct stat *status);
+
+PyAPI_FUNC(int) _Py_open(
+ const char *pathname,
+ int flags);
+
+PyAPI_FUNC(int) _Py_open_noraise(
+ const char *pathname,
+ int flags);
+
+PyAPI_FUNC(FILE *) _Py_wfopen(
+ const wchar_t *path,
+ const wchar_t *mode);
+
+PyAPI_FUNC(FILE*) _Py_fopen(
+ const char *pathname,
+ const char *mode);
+
+PyAPI_FUNC(FILE*) _Py_fopen_obj(
+ PyObject *path,
+ const char *mode);
+
+PyAPI_FUNC(Py_ssize_t) _Py_read(
+ int fd,
+ void *buf,
+ size_t count);
+
+PyAPI_FUNC(Py_ssize_t) _Py_write(
+ int fd,
+ const void *buf,
+ size_t count);
+
+PyAPI_FUNC(Py_ssize_t) _Py_write_noraise(
+ int fd,
+ const void *buf,
+ size_t count);
+
+#ifdef HAVE_READLINK
+PyAPI_FUNC(int) _Py_wreadlink(
+ const wchar_t *path,
+ wchar_t *buf,
+ size_t bufsiz);
+#endif
+
+#ifdef HAVE_REALPATH
+PyAPI_FUNC(wchar_t*) _Py_wrealpath(
+ const wchar_t *path,
+ wchar_t *resolved_path,
+ size_t resolved_path_size);
+#endif
+
+PyAPI_FUNC(wchar_t*) _Py_wgetcwd(
+ wchar_t *buf,
+ size_t size);
+
+PyAPI_FUNC(int) _Py_get_inheritable(int fd);
+
+PyAPI_FUNC(int) _Py_set_inheritable(int fd, int inheritable,
+ int *atomic_flag_works);
+
+PyAPI_FUNC(int) _Py_set_inheritable_async_safe(int fd, int inheritable,
+ int *atomic_flag_works);
+
+PyAPI_FUNC(int) _Py_dup(int fd);
+
+#ifndef MS_WINDOWS
+PyAPI_FUNC(int) _Py_get_blocking(int fd);
+
+PyAPI_FUNC(int) _Py_set_blocking(int fd, int blocking);
+#endif /* !MS_WINDOWS */
+
+PyAPI_FUNC(int) _Py_GetLocaleconvNumeric(
+ PyObject **decimal_point,
+ PyObject **thousands_sep,
+ const char **grouping);
+
+#endif /* Py_LIMITED_API */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_FILEUTILS_H */
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/osdefs.h b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/osdefs.h
new file mode 100644
index 00000000..98ce842c
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/osdefs.h
@@ -0,0 +1,51 @@
+#ifndef Py_OSDEFS_H
+#define Py_OSDEFS_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Operating system dependencies */
+
+#ifdef MS_WINDOWS
+#define SEP L'\\'
+#define ALTSEP L'/'
+#define MAXPATHLEN 256
+#define DELIM L';'
+#endif
+
+/* Filename separator */
+#ifndef SEP
+#define SEP L'/'
+#endif
+
+/* Max pathname length */
+#ifdef __hpux
+#include <sys/param.h>
+#include <limits.h>
+#ifndef PATH_MAX
+#define PATH_MAX MAXPATHLEN
+#endif
+#endif
+
+#ifndef MAXPATHLEN
+#if defined(PATH_MAX) && PATH_MAX > 1024
+#define MAXPATHLEN PATH_MAX
+#else
+#define MAXPATHLEN 1024
+#endif
+#endif
+
+/* Search path entry delimiter */
+#ifndef DELIM
+#ifndef UEFI_C_SOURCE
+#define DELIM L':'
+#else
+#define DELIM L';'
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_OSDEFS_H */
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyconfig.h b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyconfig.h
new file mode 100644
index 00000000..d4685da3
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyconfig.h
@@ -0,0 +1,1322 @@
+/** @file
+ Manually generated Python Configuration file for EDK II.
+
+ Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are licensed and made available under
+ the terms and conditions of the BSD License that accompanies this distribution.
+ The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+#ifndef Py_PYCONFIG_H
+#define Py_PYCONFIG_H
+#ifdef UEFI_C_SOURCE
+#include <Uefi.h>
+#define PLATFORM "uefi"
+#define _rotl64(a, offset) (a << offset) | (a >> (64 - offset))
+#endif
+#define Py_BUILD_CORE
+
+//#define Py_LIMITED_API=0x03060000
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
+ support for AIX C++ shared extension modules. */
+#undef AIX_GENUINE_CPLUSPLUS
+
+/* Define this if you have AtheOS threads. */
+#undef ATHEOS_THREADS
+
+/* Define this if you have BeOS threads. */
+#undef BEOS_THREADS
+
+/* Define if you have the Mach cthreads package */
+#undef C_THREADS
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored in ARM
+ mixed-endian order (byte order 45670123) */
+#undef DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the most
+ significant byte first */
+#undef DOUBLE_IS_BIG_ENDIAN_IEEE754
+
+/* Define if C doubles are 64-bit IEEE 754 binary format, stored with the
+ least significant byte first */
+#define DOUBLE_IS_LITTLE_ENDIAN_IEEE754
+
+/* Define if --enable-ipv6 is specified */
+#undef ENABLE_IPV6
+
+/* Define if flock needs to be linked with bsd library. */
+#undef FLOCK_NEEDS_LIBBSD
+
+/* Define if getpgrp() must be called as getpgrp(0). */
+#undef GETPGRP_HAVE_ARG
+
+/* Define if gettimeofday() does not have second (timezone) argument This is
+ the case on Motorola V4 (R40V4.2) */
+#undef GETTIMEOFDAY_NO_TZ
+
+/* Define to 1 if you have the 'acosh' function. */
+#undef HAVE_ACOSH
+
+/* struct addrinfo (netdb.h) */
+#undef HAVE_ADDRINFO
+
+/* Define to 1 if you have the 'alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define this if your time.h defines altzone. */
+#undef HAVE_ALTZONE
+
+/* Define to 1 if you have the 'asinh' function. */
+#undef HAVE_ASINH
+
+/* Define to 1 if you have the <asm/types.h> header file. */
+#undef HAVE_ASM_TYPES_H
+
+/* Define to 1 if you have the 'atanh' function. */
+#undef HAVE_ATANH
+
+/* Define if GCC supports __attribute__((format(PyArg_ParseTuple, 2, 3))) */
+#undef HAVE_ATTRIBUTE_FORMAT_PARSETUPLE
+
+/* Define to 1 if you have the 'bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
+/* Define to 1 if you have the <bluetooth/bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_BLUETOOTH_H
+
+/* Define to 1 if you have the <bluetooth.h> header file. */
+#undef HAVE_BLUETOOTH_H
+
+/* Define if nice() returns success/failure instead of the new priority. */
+#undef HAVE_BROKEN_NICE
+
+/* Define if the system reports an invalid PIPE_BUF value. */
+#undef HAVE_BROKEN_PIPE_BUF
+
+/* Define if poll() sets errno on invalid file descriptors. */
+#undef HAVE_BROKEN_POLL
+
+/* Define if the Posix semaphores do not work on your system */
+#define HAVE_BROKEN_POSIX_SEMAPHORES 1
+
+/* Define if pthread_sigmask() does not work on your system. */
+#define HAVE_BROKEN_PTHREAD_SIGMASK 1
+
+/* define to 1 if your sem_getvalue is broken. */
+#define HAVE_BROKEN_SEM_GETVALUE 1
+
+/* Define if 'unsetenv' does not return an int. */
+#undef HAVE_BROKEN_UNSETENV
+
+/* Define this if you have the type _Bool. */
+#define HAVE_C99_BOOL 1
+
+/* Define to 1 if you have the 'chflags' function. */
+#undef HAVE_CHFLAGS
+
+/* Define to 1 if you have the 'chown' function. */
+#undef HAVE_CHOWN
+
+/* Define if you have the 'chroot' function. */
+#undef HAVE_CHROOT
+
+/* Define to 1 if you have the 'clock' function. */
+#define HAVE_CLOCK 1
+
+/* Define to 1 if you have the 'confstr' function. */
+#undef HAVE_CONFSTR
+
+/* Define to 1 if you have the <conio.h> header file. */
+#undef HAVE_CONIO_H
+
+/* Define to 1 if you have the 'copysign' function. */
+#define HAVE_COPYSIGN 1
+
+/* Define to 1 if you have the 'ctermid' function. */
+#undef HAVE_CTERMID
+
+/* Define if you have the 'ctermid_r' function. */
+#undef HAVE_CTERMID_R
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if you have the 'is_term_resized' function. */
+#undef HAVE_CURSES_IS_TERM_RESIZED
+
+/* Define if you have the 'resizeterm' function. */
+#undef HAVE_CURSES_RESIZETERM
+
+/* Define if you have the 'resize_term' function. */
+#undef HAVE_CURSES_RESIZE_TERM
+
+/* Define to 1 if you have the declaration of 'isfinite', and to 0 if you
+ don't. */
+#define HAVE_DECL_ISFINITE 0
+
+/* Define to 1 if you have the declaration of 'isinf', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISINF 1
+
+/* Define to 1 if you have the declaration of 'isnan', and to 0 if you don't.
+ */
+#define HAVE_DECL_ISNAN 1
+
+/* Define to 1 if you have the declaration of 'tzname', and to 0 if you don't.
+ */
+#define HAVE_DECL_TZNAME 0
+
+/* Define to 1 if you have the device macros. */
+#undef HAVE_DEVICE_MACROS
+
+/* Define to 1 if you have the /dev/ptc device file. */
+#undef HAVE_DEV_PTC
+
+/* Define to 1 if you have the /dev/ptmx device file. */
+#undef HAVE_DEV_PTMX
+
+/* Define to 1 if you have the <direct.h> header file. */
+#undef HAVE_DIRECT_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines 'DIR'. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the 'dlopen' function. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the 'dup2' function. */
+#define HAVE_DUP2 1
+
+/* Defined when any dynamic module loading is enabled. */
+#undef HAVE_DYNAMIC_LOADING
+
+/* Define if you have the 'epoll' functions. */
+#undef HAVE_EPOLL
+
+/* Define to 1 if you have the 'erf' function. */
+#undef HAVE_ERF
+
+/* Define to 1 if you have the 'erfc' function. */
+#undef HAVE_ERFC
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the 'execv' function. */
+#undef HAVE_EXECV
+
+/* Define to 1 if you have the 'expm1' function. */
+#undef HAVE_EXPM1
+
+/* Define if you have the 'fchdir' function. */
+#undef HAVE_FCHDIR
+
+/* Define to 1 if you have the 'fchmod' function. */
+#undef HAVE_FCHMOD
+
+/* Define to 1 if you have the 'fchown' function. */
+#undef HAVE_FCHOWN
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the 'fdatasync' function. */
+#undef HAVE_FDATASYNC
+
+/* Define to 1 if you have the 'finite' function. */
+#define HAVE_FINITE 1
+
+/* Define to 1 if you have the 'flock' function. */
+#undef HAVE_FLOCK
+
+/* Define to 1 if you have the 'fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the 'forkpty' function. */
+#undef HAVE_FORKPTY
+
+/* Define to 1 if you have the 'fpathconf' function. */
+#undef HAVE_FPATHCONF
+
+/* Define to 1 if you have the 'fseek64' function. */
+#undef HAVE_FSEEK64
+
+/* Define to 1 if you have the 'fseeko' function. */
+#define HAVE_FSEEKO 1
+
+/* Define to 1 if you have the 'fstatvfs' function. */
+#undef HAVE_FSTATVFS
+
+/* Define if you have the 'fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the 'ftell64' function. */
+#undef HAVE_FTELL64
+
+/* Define to 1 if you have the 'ftello' function. */
+#define HAVE_FTELLO 1
+
+/* Define to 1 if you have the 'ftime' function. */
+#undef HAVE_FTIME
+
+/* Define to 1 if you have the 'ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the 'gai_strerror' function. */
+#undef HAVE_GAI_STRERROR
+
+/* Define to 1 if you have the 'gamma' function. */
+#undef HAVE_GAMMA
+
+/* Define if we can use gcc inline assembler to get and set x87 control word */
+#if defined(__GNUC__)
+ #define HAVE_GCC_ASM_FOR_X87 1
+#else
+ #undef HAVE_GCC_ASM_FOR_X87
+#endif
+
+/* Define if you have the getaddrinfo function. */
+//#undef HAVE_GETADDRINFO
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if you have the 'getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+#undef HAVE_GETC_UNLOCKED
+
+/* Define to 1 if you have the 'getentropy' function. */
+#undef HAVE_GETENTROPY
+
+/* Define to 1 if you have the 'getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the 'gethostbyname' function. */
+//#undef HAVE_GETHOSTBYNAME
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define this if you have some version of gethostbyname_r() */
+#undef HAVE_GETHOSTBYNAME_R
+
+/* Define this if you have the 3-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_3_ARG
+
+/* Define this if you have the 5-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_5_ARG
+
+/* Define this if you have the 6-arg version of gethostbyname_r(). */
+#undef HAVE_GETHOSTBYNAME_R_6_ARG
+
+/* Define to 1 if you have the 'getitimer' function. */
+#undef HAVE_GETITIMER
+
+/* Define to 1 if you have the 'getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the 'getlogin' function. */
+#undef HAVE_GETLOGIN
+
+/* Define to 1 if you have the 'getnameinfo' function. */
+//#undef HAVE_GETNAMEINFO
+#define HAVE_GETNAMEINFO 1
+
+/* Define if you have the 'getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the 'getpeername' function. */
+#define HAVE_GETPEERNAME 1
+
+/* Define to 1 if you have the 'getpgid' function. */
+#undef HAVE_GETPGID
+
+/* Define to 1 if you have the 'getpgrp' function. */
+#undef HAVE_GETPGRP
+
+/* Define to 1 if you have the 'getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the 'getpriority' function. */
+#undef HAVE_GETPRIORITY
+
+/* Define to 1 if you have the 'getpwent' function. */
+#undef HAVE_GETPWENT
+
+/* Define to 1 if you have the 'getresgid' function. */
+#undef HAVE_GETRESGID
+
+/* Define to 1 if you have the 'getresuid' function. */
+#undef HAVE_GETRESUID
+
+/* Define to 1 if you have the 'getsid' function. */
+#undef HAVE_GETSID
+
+/* Define to 1 if you have the 'getspent' function. */
+#undef HAVE_GETSPENT
+
+/* Define to 1 if you have the 'getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the 'gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the 'getwd' function. */
+#undef HAVE_GETWD
+
+/* Define to 1 if you have the <grp.h> header file. */
+#undef HAVE_GRP_H
+
+/* Define if you have the 'hstrerror' function. */
+#undef HAVE_HSTRERROR
+
+/* Define to 1 if you have the 'hypot' function. */
+#undef HAVE_HYPOT
+
+/* Define to 1 if you have the <ieeefp.h> header file. */
+#undef HAVE_IEEEFP_H
+
+/* Define if you have the 'inet_aton' function. */
+#define HAVE_INET_ATON 1
+
+/* Define if you have the 'inet_pton' function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the 'initgroups' function. */
+#undef HAVE_INITGROUPS
+
+/* Define if your compiler provides int32_t. */
+#undef HAVE_INT32_T
+
+/* Define if your compiler provides int64_t. */
+#undef HAVE_INT64_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <io.h> header file. */
+#undef HAVE_IO_H
+
+/* Define to 1 if you have the 'kill' function. */
+#undef HAVE_KILL
+
+/* Define to 1 if you have the 'killpg' function. */
+#undef HAVE_KILLPG
+
+/* Define if you have the 'kqueue' functions. */
+#undef HAVE_KQUEUE
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H /* non-functional in EFI. */
+
+/* Defined to enable large file support when an off_t is bigger than a long
+ and long long is available and at least as big as an off_t. You may need to
+ add some flags for configuration and compilation to enable this mode. (For
+ Solaris and Linux, the necessary defines are already defined.) */
+#undef HAVE_LARGEFILE_SUPPORT
+
+/* Define to 1 if you have the 'lchflags' function. */
+#undef HAVE_LCHFLAGS
+
+/* Define to 1 if you have the 'lchmod' function. */
+#undef HAVE_LCHMOD
+
+/* Define to 1 if you have the 'lchown' function. */
+#undef HAVE_LCHOWN
+
+/* Define to 1 if you have the 'lgamma' function. */
+#undef HAVE_LGAMMA
+
+/* Define to 1 if you have the 'dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the 'dld' library (-ldld). */
+#undef HAVE_LIBDLD
+
+/* Define to 1 if you have the 'ieee' library (-lieee). */
+#undef HAVE_LIBIEEE
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define if you have the readline library (-lreadline). */
+#undef HAVE_LIBREADLINE
+
+/* Define to 1 if you have the 'resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the <libutil.h> header file. */
+#undef HAVE_LIBUTIL_H
+
+/* Define if you have the 'link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the <linux/netlink.h> header file. */
+#undef HAVE_LINUX_NETLINK_H
+
+/* Define to 1 if you have the <linux/tipc.h> header file. */
+#undef HAVE_LINUX_TIPC_H
+
+/* Define to 1 if you have the 'log1p' function. */
+#undef HAVE_LOG1P
+
+/* Define this if you have the type long double. */
+#undef HAVE_LONG_DOUBLE
+
+/* Define this if you have the type long long. */
+#define HAVE_LONG_LONG 1
+
+/* Define to 1 if you have the 'lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define this if you have the makedev macro. */
+#undef HAVE_MAKEDEV
+
+/* Define to 1 if you have the 'memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the 'mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the 'mknod' function. */
+#undef HAVE_MKNOD
+
+/* Define to 1 if you have the 'mktime' function. */
+#define HAVE_MKTIME 1
+
+/* Define to 1 if you have the 'mmap' function. */
+#undef HAVE_MMAP
+
+/* Define to 1 if you have the 'mremap' function. */
+#undef HAVE_MREMAP
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines 'DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netpacket/packet.h> header file. */
+#undef HAVE_NETPACKET_PACKET_H
+
+/* Define to 1 if you have the 'nice' function. */
+#undef HAVE_NICE
+
+/* Define to 1 if you have the 'openpty' function. */
+#undef HAVE_OPENPTY
+
+/* Define if compiling using MacOS X 10.5 SDK or later. */
+#undef HAVE_OSX105_SDK
+
+/* Define to 1 if you have the 'pathconf' function. */
+#undef HAVE_PATHCONF
+
+/* Define to 1 if you have the 'pause' function. */
+#undef HAVE_PAUSE
+
+/* Define to 1 if you have the 'plock' function. */
+#undef HAVE_PLOCK
+
+/* Define to 1 if you have the 'poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#undef HAVE_POLL_H
+
+/* Define to 1 if you have the <process.h> header file. */
+#undef HAVE_PROCESS_H
+
+/* Define if your compiler supports function prototype */
+#define HAVE_PROTOTYPES 1
+
+/* Define if you have GNU PTH threads. */
+#undef HAVE_PTH
+
+/* Define to 1 if you have the 'pthread_atfork' function. */
+#undef HAVE_PTHREAD_ATFORK
+
+/* Defined for Solaris 2.6 bug in pthread header. */
+#undef HAVE_PTHREAD_DESTRUCTOR
+
+/* Define to 1 if you have the <pthread.h> header file. */
+#undef HAVE_PTHREAD_H
+
+/* Define to 1 if you have the 'pthread_init' function. */
+#undef HAVE_PTHREAD_INIT
+
+/* Define to 1 if you have the 'pthread_sigmask' function. */
+#undef HAVE_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the <pty.h> header file. */
+#undef HAVE_PTY_H
+
+/* Define to 1 if you have the 'putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define if the libcrypto has RAND_egd */
+#undef HAVE_RAND_EGD
+
+/* Define to 1 if you have the 'readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the 'realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define if you have readline 2.1 */
+#undef HAVE_RL_CALLBACK
+
+/* Define if you can turn off readline's signal handling. */
+#undef HAVE_RL_CATCH_SIGNAL
+
+/* Define if you have readline 2.2 */
+#undef HAVE_RL_COMPLETION_APPEND_CHARACTER
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
+
+/* Define if you have readline 4.2 */
+#undef HAVE_RL_COMPLETION_MATCHES
+
+/* Define if you have rl_completion_suppress_append */
+#undef HAVE_RL_COMPLETION_SUPPRESS_APPEND
+
+/* Define if you have readline 4.0 */
+#undef HAVE_RL_PRE_INPUT_HOOK
+
+/* Define to 1 if you have the 'round' function. */
+#undef HAVE_ROUND
+
+/* Define to 1 if you have the 'select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the 'sem_getvalue' function. */
+#undef HAVE_SEM_GETVALUE
+
+/* Define to 1 if you have the 'sem_open' function. */
+#undef HAVE_SEM_OPEN
+
+/* Define to 1 if you have the 'sem_timedwait' function. */
+#undef HAVE_SEM_TIMEDWAIT
+
+/* Define to 1 if you have the 'sem_unlink' function. */
+#undef HAVE_SEM_UNLINK
+
+/* Define to 1 if you have the 'setegid' function. */
+#undef HAVE_SETEGID
+
+/* Define to 1 if you have the 'seteuid' function. */
+#undef HAVE_SETEUID
+
+/* Define to 1 if you have the 'setgid' function. */
+#undef HAVE_SETGID
+
+/* Define if you have the 'setgroups' function. */
+#undef HAVE_SETGROUPS
+
+/* Define to 1 if you have the 'setitimer' function. */
+#undef HAVE_SETITIMER
+
+/* Define to 1 if you have the 'setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the 'setpgid' function. */
+#undef HAVE_SETPGID
+
+/* Define to 1 if you have the 'setpgrp' function. */
+#undef HAVE_SETPGRP
+
+/* Define to 1 if you have the 'setregid' function. */
+#undef HAVE_SETREGID
+
+/* Define to 1 if you have the 'setresgid' function. */
+#undef HAVE_SETRESGID
+
+/* Define to 1 if you have the 'setresuid' function. */
+#undef HAVE_SETRESUID
+
+/* Define to 1 if you have the 'setreuid' function. */
+#undef HAVE_SETREUID
+
+/* Define to 1 if you have the 'setsid' function. */
+#undef HAVE_SETSID
+
+/* Define to 1 if you have the 'setuid' function. */
+#undef HAVE_SETUID
+
+/* Define to 1 if you have the 'setvbuf' function. */
+#define HAVE_SETVBUF 1
+
+/* Define to 1 if you have the <shadow.h> header file. */
+#undef HAVE_SHADOW_H
+
+/* Define to 1 if you have the 'sigaction' function. */
+#undef HAVE_SIGACTION
+
+/* Define to 1 if you have the 'siginterrupt' function. */
+#undef HAVE_SIGINTERRUPT
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if you have the 'sigrelse' function. */
+#undef HAVE_SIGRELSE
+
+/* Define to 1 if you have the 'snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define if sockaddr has sa_len member */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* struct sockaddr_storage (sys/socket.h) */
+#undef HAVE_SOCKADDR_STORAGE
+
+/* Define if you have the 'socketpair' function. */
+#undef HAVE_SOCKETPAIR
+
+/* Define to 1 if you have the <spawn.h> header file. */
+#undef HAVE_SPAWN_H
+
+/* Define if your compiler provides ssize_t */
+#define HAVE_SSIZE_T 1
+
+/* Define to 1 if you have the 'statvfs' function. */
+#undef HAVE_STATVFS
+
+/* Define if you have struct stat.st_mtim.tv_nsec */
+#undef HAVE_STAT_TV_NSEC
+
+/* Define if you have struct stat.st_mtimensec */
+#undef HAVE_STAT_TV_NSEC2
+
+/* Define if your compiler supports variable length function prototypes (e.g.
+ void fprintf(FILE *, char *, ...);) *and* <stdarg.h> */
+#define HAVE_STDARG_PROTOTYPES 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the 'strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the 'strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#undef HAVE_STROPTS_H
+
+/* Define to 1 if 'st_birthtime' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1
+
+/* Define to 1 if 'st_blksize' is a member of 'struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if 'st_blocks' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLOCKS
+
+/* Define to 1 if 'st_flags' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_FLAGS
+
+/* Define to 1 if 'st_gen' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_GEN
+
+/* Define to 1 if 'st_rdev' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_RDEV
+
+/* Define to 1 if 'st_dev' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_DEV
+
+/* Define to 1 if 'st_ino' is a member of 'struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_INO
+
+/* Define to 1 if 'tm_zone' is a member of 'struct tm'. */
+#undef HAVE_STRUCT_TM_TM_ZONE
+
+/* Define to 1 if your 'struct stat' has 'st_blocks'. Deprecated, use
+ 'HAVE_STRUCT_STAT_ST_BLOCKS' instead. */
+#undef HAVE_ST_BLOCKS
+
+/* Define if you have the 'symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the 'sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#undef HAVE_SYSEXITS_H
+
+/* Define to 1 if you have the <sys/audioio.h> header file. */
+#undef HAVE_SYS_AUDIOIO_H
+
+/* Define to 1 if you have the <sys/bsdtty.h> header file. */
+#undef HAVE_SYS_BSDTTY_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+#undef HAVE_SYS_EPOLL_H
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+#undef HAVE_SYS_EVENT_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/loadavg.h> header file. */
+#undef HAVE_SYS_LOADAVG_H
+
+/* Define to 1 if you have the <sys/lock.h> header file. */
+#undef HAVE_SYS_LOCK_H
+
+/* Define to 1 if you have the <sys/mkdev.h> header file. */
+#undef HAVE_SYS_MKDEV_H
+
+/* Define to 1 if you have the <sys/modem.h> header file. */
+#undef HAVE_SYS_MODEM_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines 'DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/termio.h> header file. */
+#undef HAVE_SYS_TERMIO_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the system() command. */
+#define HAVE_SYSTEM 1
+
+/* Define to 1 if you have the 'tcgetpgrp' function. */
+#undef HAVE_TCGETPGRP
+
+/* Define to 1 if you have the 'tcsetpgrp' function. */
+#undef HAVE_TCSETPGRP
+
+/* Define to 1 if you have the 'tempnam' function. */
+#define HAVE_TEMPNAM 1
+
+/* Define to 1 if you have the <termios.h> header file. */
+#undef HAVE_TERMIOS_H
+
+/* Define to 1 if you have the <term.h> header file. */
+#undef HAVE_TERM_H
+
+/* Define to 1 if you have the 'tgamma' function. */
+#undef HAVE_TGAMMA
+
+/* Define to 1 if you have the <thread.h> header file. */
+#undef HAVE_THREAD_H
+
+/* Define to 1 if you have the 'timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the 'times' function. */
+#undef HAVE_TIMES
+
+/* Define to 1 if you have the 'tmpfile' function. */
+#define HAVE_TMPFILE 1
+
+/* Define to 1 if you have the 'tmpnam' function. */
+#define HAVE_TMPNAM 1
+
+/* Define to 1 if you have the 'tmpnam_r' function. */
+#undef HAVE_TMPNAM_R
+
+/* Define to 1 if your 'struct tm' has 'tm_zone'. Deprecated, use
+ 'HAVE_STRUCT_TM_TM_ZONE' instead. */
+#undef HAVE_TM_ZONE
+
+/* Define to 1 if you have the 'truncate' function. */
+#undef HAVE_TRUNCATE
+
+/* Define to 1 if you don't have 'tm_zone' but do have the external array
+ 'tzname'. */
+#undef HAVE_TZNAME
+
+/* Define this if you have tcl and TCL_UTF_MAX==6 */
+#undef HAVE_UCS4_TCL
+
+/* Define if your compiler provides uint32_t. */
+#undef HAVE_UINT32_T
+
+/* Define if your compiler provides uint64_t. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if the system has the type 'uintptr_t'. */
+#define HAVE_UINTPTR_T 1
+
+/* Define to 1 if you have the 'uname' function. */
+#undef HAVE_UNAME
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the 'unsetenv' function. */
+#undef HAVE_UNSETENV
+
+/* Define if you have a useable wchar_t type defined in wchar.h; useable means
+ wchar_t must be an unsigned type with at least 16 bits. (see
+ Include/unicodeobject.h). */
+#define HAVE_USABLE_WCHAR_T 1
+
+/* Define to 1 if you have the <util.h> header file. */
+#undef HAVE_UTIL_H
+
+/* Define to 1 if you have the 'utimes' function. */
+#undef HAVE_UTIMES
+
+/* Define to 1 if you have the <utime.h> header file. */
+#define HAVE_UTIME_H 1
+
+/* Define to 1 if you have the 'wait3' function. */
+#undef HAVE_WAIT3
+
+/* Define to 1 if you have the 'wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the 'waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define if the compiler provides a wchar.h header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the 'wcscoll' function. */
+#define HAVE_WCSCOLL 1
+
+/* Define if tzset() actually switches the local timezone in a meaningful way.
+ */
+#undef HAVE_WORKING_TZSET
+
+/* Define if the zlib library has inflateCopy */
+#undef HAVE_ZLIB_COPY
+
+/* Define to 1 if you have the '_getpty' function. */
+#undef HAVE__GETPTY
+
+/* Define if you are using Mach cthreads directly under /include */
+#undef HURD_C_THREADS
+
+/* Define if you are using Mach cthreads under mach / */
+#undef MACH_C_THREADS
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in <mkdev.h>.
+ */
+#undef MAJOR_IN_MKDEV
+
+/* Define to 1 if 'major', 'minor', and 'makedev' are declared in
+ <sysmacros.h>. */
+#undef MAJOR_IN_SYSMACROS
+
+/* Define if mvwdelch in curses.h is an expression. */
+#undef MVWDELCH_IS_EXPRESSION
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "edk2-devel@lists.01.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "EDK II Python 2.7.10 Package"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "EDK II Python 2.7.10 Package V0.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "EADK_Python"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL "http://www.tianocore.org/"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "V0.1"
+
+/* Define if POSIX semaphores aren't enabled on your system */
+#define POSIX_SEMAPHORES_NOT_ENABLED 1
+
+/* Defined if PTHREAD_SCOPE_SYSTEM supported. */
+#undef PTHREAD_SYSTEM_SCHED_SUPPORTED
+
+/* Define as the preferred size in bits of long digits */
+#undef PYLONG_BITS_IN_DIGIT
+
+/* Define to printf format modifier for long long type */
+#define PY_FORMAT_LONG_LONG "ll"
+
+/* Define to printf format modifier for Py_ssize_t */
+#define PY_FORMAT_SIZE_T "z"
+
+/* Define as the integral type used for Unicode representation. */
+#define PY_UNICODE_TYPE wchar_t
+
+/* Define if you want to build an interpreter with many run-time checks. */
+#undef Py_DEBUG
+
+/* Defined if Python is built as a shared library. */
+#undef Py_ENABLE_SHARED
+
+/* Define if you want to have a Unicode type. */
+#define Py_USING_UNICODE
+
+/* assume C89 semantics that RETSIGTYPE is always void */
+#undef RETSIGTYPE
+
+/* Define if setpgrp() must be called as setpgrp(0, 0). */
+#undef SETPGRP_HAVE_ARG
+
+/* Define this to be extension of shared libraries (including the dot!). */
+#undef SHLIB_EXT
+
+/* Define if i>>j for signed int i does not extend the sign bit when i < 0 */
+#undef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+
+/* The size of 'double', as computed by sizeof. */
+#define SIZEOF_DOUBLE 8
+
+/* The size of 'float', as computed by sizeof. */
+#define SIZEOF_FLOAT 4
+
+/* The size of 'fpos_t', as computed by sizeof. */
+#define SIZEOF_FPOS_T 8
+
+/* The size of 'int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of 'long', as computed by sizeof. */
+#if defined(_MSC_VER) /* Handle Microsoft VC++ compiler specifics. */
+#define SIZEOF_LONG 4
+#else
+#define SIZEOF_LONG 8
+#endif
+
+/* The size of 'long double', as computed by sizeof. */
+#undef SIZEOF_LONG_DOUBLE
+
+/* The size of 'long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of 'off_t', as computed by sizeof. */
+#ifdef UEFI_MSVC_64
+#define SIZEOF_OFF_T 8
+#else
+#define SIZEOF_OFF_T 4
+#endif
+
+
+/* The size of 'pid_t', as computed by sizeof. */
+#define SIZEOF_PID_T 4
+
+/* The size of 'pthread_t', as computed by sizeof. */
+#undef SIZEOF_PTHREAD_T
+
+/* The size of 'short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of 'size_t', as computed by sizeof. */
+#ifdef UEFI_MSVC_64
+#define SIZEOF_SIZE_T 8
+#else
+#define SIZEOF_SIZE_T 4
+#endif
+
+/* The size of 'time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* The size of 'uintptr_t', as computed by sizeof. */
+#ifdef UEFI_MSVC_64
+#define SIZEOF_UINTPTR_T 8
+#else
+#define SIZEOF_UINTPTR_T 4
+#endif
+
+/* The size of 'void *', as computed by sizeof. */
+#ifdef UEFI_MSVC_64
+#define SIZEOF_VOID_P 8
+#else
+#define SIZEOF_VOID_P 4
+#endif
+
+/* The size of 'wchar_t', as computed by sizeof. */
+#define SIZEOF_WCHAR_T 2
+
+/* The size of '_Bool', as computed by sizeof. */
+#define SIZEOF__BOOL 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/select.h> and <sys/time.h>
+ (which you can't on SCO ODT 3.0). */
+#undef SYS_SELECT_WITH_SYS_TIME
+
+/* Define if tanh(-0.) is -0., or if platform doesn't have signed zeros */
+#undef TANH_PRESERVES_ZERO_SIGN
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares 'struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define if you want to use MacPython modules on MacOSX in unix-Python. */
+#undef USE_TOOLBOX_OBJECT_GLUE
+
+/* Define if a va_list is an array of some kind */
+#undef VA_LIST_IS_ARRAY
+
+/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
+#undef WANT_SIGFPE_HANDLER
+
+/* Define if you want wctype.h functions to be used instead of the one
+ supplied by Python itself. (see Include/unicodectype.h). */
+#define WANT_WCTYPE_FUNCTIONS 1
+
+/* Define if WINDOW in curses.h offers a field _flags. */
+#undef WINDOW_HAS_FLAGS
+
+/* Define if you want documentation strings in extension modules */
+#undef WITH_DOC_STRINGS
+
+/* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic
+ linker (dyld) instead of the old-style (NextStep) dynamic linker (rld).
+ Dyld is necessary to support frameworks. */
+#undef WITH_DYLD
+
+/* Define to 1 if libintl is needed for locale functions. */
+#undef WITH_LIBINTL
+
+/* Define if you want to produce an OpenStep/Rhapsody framework (shared
+ library plus accessory files). */
+#undef WITH_NEXT_FRAMEWORK
+
+/* Define if you want to compile in Python-specific mallocs */
+#undef WITH_PYMALLOC
+
+/* Define if you want to compile in rudimentary thread support */
+#undef WITH_THREAD
+
+/* Define to profile with the Pentium timestamp counter */
+#undef WITH_TSC
+
+/* Define if you want pymalloc to be disabled when running under valgrind */
+#undef WITH_VALGRIND
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define if arithmetic is subject to x87-style double rounding issue */
+#undef X87_DOUBLE_ROUNDING
+
+/* Define on OpenBSD to activate all library features */
+#undef _BSD_SOURCE
+
+/* Define on Irix to enable u_int */
+#undef _BSD_TYPES
+
+/* Define on Darwin to activate all library features */
+#undef _DARWIN_C_SOURCE
+
+/* This must be set to 64 on some systems to enable large file support. */
+#undef _FILE_OFFSET_BITS
+
+/* Define on Linux to activate all library features */
+#undef _GNU_SOURCE
+
+/* This must be defined on some systems to enable large file support. */
+#undef _LARGEFILE_SOURCE
+
+/* This must be defined on AIX systems to enable large file support. */
+#undef _LARGE_FILES
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define on NetBSD to activate all library features */
+#define _NETBSD_SOURCE 1
+
+/* Define _OSF_SOURCE to get the makedev macro. */
+#undef _OSF_SOURCE
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to activate features from IEEE Stds 1003.1-2001 */
+#undef _POSIX_C_SOURCE
+
+/* Define to 1 if you need to in order for 'stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if you have POSIX threads, and your system does not define that. */
+#undef _POSIX_THREADS
+
+/* Define to force use of thread-safe errno, h_errno, and other functions */
+#undef _REENTRANT
+
+/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT32_T
+
+/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
+ <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
+ #define below would cause a syntax error. */
+#undef _UINT64_T
+
+/* Define to the level of X/Open that your system supports */
+#undef _XOPEN_SOURCE
+
+/* Define to activate Unix95-and-earlier features */
+#undef _XOPEN_SOURCE_EXTENDED
+
+/* Define on FreeBSD to activate all library features */
+#undef __BSD_VISIBLE
+
+/* Define to 1 if type 'char' is unsigned and you are not using gcc. */
+#ifndef __CHAR_UNSIGNED__
+# undef __CHAR_UNSIGNED__
+#endif
+
+/* Defined on Solaris to see additional function prototypes. */
+#undef __EXTENSIONS__
+
+/* Define to 'long' if <time.h> doesn't define. */
+//#undef clock_t
+
+/* Define to empty if 'const' does not conform to ANSI C. */
+//#undef const
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef gid_t
+
+/* Define to the type of a signed integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int32_t
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef int64_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef mode_t
+
+/* Define to 'long int' if <sys/types.h> does not define. */
+//#undef off_t
+
+/* Define to 'int' if <sys/types.h> does not define. */
+//#undef pid_t
+
+/* Define to empty if the keyword does not work. */
+//#undef signed
+
+/* Define to 'unsigned int' if <sys/types.h> does not define. */
+//#undef size_t
+
+/* Define to 'int' if <sys/socket.h> does not define. */
+//#undef socklen_t
+
+/* Define to 'int' if <sys/types.h> doesn't define. */
+//#undef uid_t
+
+/* Define to the type of an unsigned integer type of width exactly 32 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint32_t
+
+/* Define to the type of an unsigned integer type of width exactly 64 bits if
+ such a type exists and the standard includes do not define it. */
+//#undef uint64_t
+
+/* Define to empty if the keyword does not work. */
+//#undef volatile
+
+#endif /*Py_PYCONFIG_H*/
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pydtrace.h b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pydtrace.h
new file mode 100644
index 00000000..a463004d
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pydtrace.h
@@ -0,0 +1,74 @@
+/* Static DTrace probes interface */
+
+#ifndef Py_DTRACE_H
+#define Py_DTRACE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef WITH_DTRACE
+
+#include "pydtrace_probes.h"
+
+/* pydtrace_probes.h, on systems with DTrace, is auto-generated to include
+ `PyDTrace_{PROBE}` and `PyDTrace_{PROBE}_ENABLED()` macros for every probe
+ defined in pydtrace_provider.d.
+
+ Calling these functions must be guarded by a `PyDTrace_{PROBE}_ENABLED()`
+ check to minimize performance impact when probing is off. For example:
+
+ if (PyDTrace_FUNCTION_ENTRY_ENABLED())
+ PyDTrace_FUNCTION_ENTRY(f);
+*/
+
+#else
+
+/* Without DTrace, compile to nothing. */
+#ifndef UEFI_C_SOURCE
+static inline void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) {}
+static inline void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {}
+static inline void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {}
+static inline void PyDTrace_GC_START(int arg0) {}
+static inline void PyDTrace_GC_DONE(int arg0) {}
+static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {}
+static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {}
+static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {}
+static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {}
+
+static inline int PyDTrace_LINE_ENABLED(void) { return 0; }
+static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; }
+static inline int PyDTrace_FUNCTION_RETURN_ENABLED(void) { return 0; }
+static inline int PyDTrace_GC_START_ENABLED(void) { return 0; }
+static inline int PyDTrace_GC_DONE_ENABLED(void) { return 0; }
+static inline int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; }
+static inline int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; }
+static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; }
+static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; }
+#else
+static void PyDTrace_LINE(const char *arg0, const char *arg1, int arg2) {}
+static void PyDTrace_FUNCTION_ENTRY(const char *arg0, const char *arg1, int arg2) {}
+static void PyDTrace_FUNCTION_RETURN(const char *arg0, const char *arg1, int arg2) {}
+static void PyDTrace_GC_START(int arg0) {}
+static void PyDTrace_GC_DONE(int arg0) {}
+static void PyDTrace_INSTANCE_NEW_START(int arg0) {}
+static void PyDTrace_INSTANCE_NEW_DONE(int arg0) {}
+static void PyDTrace_INSTANCE_DELETE_START(int arg0) {}
+static void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {}
+
+static int PyDTrace_LINE_ENABLED(void) { return 0; }
+static int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; }
+static int PyDTrace_FUNCTION_RETURN_ENABLED(void) { return 0; }
+static int PyDTrace_GC_START_ENABLED(void) { return 0; }
+static int PyDTrace_GC_DONE_ENABLED(void) { return 0; }
+static int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; }
+static int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; }
+static int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; }
+static int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; }
+#endif
+
+#endif /* !WITH_DTRACE */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_DTRACE_H */
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyport.h b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyport.h
new file mode 100644
index 00000000..ca49c295
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Include/pyport.h
@@ -0,0 +1,788 @@
+#ifndef Py_PYPORT_H
+#define Py_PYPORT_H
+
+#include "pyconfig.h" /* include for defines */
+
+/* Some versions of HP-UX & Solaris need inttypes.h for int32_t,
+ INT32_MAX, etc. */
+#ifdef UEFI_C_SOURCE
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#else
+#include <inttypes.h>
+#endif
+
+/**************************************************************************
+Symbols and macros to supply platform-independent interfaces to basic
+C language & library operations whose spellings vary across platforms.
+
+Please try to make documentation here as clear as possible: by definition,
+the stuff here is trying to illuminate C's darkest corners.
+
+Config #defines referenced here:
+
+SIGNED_RIGHT_SHIFT_ZERO_FILLS
+Meaning: To be defined iff i>>j does not extend the sign bit when i is a
+ signed integral type and i < 0.
+Used in: Py_ARITHMETIC_RIGHT_SHIFT
+
+Py_DEBUG
+Meaning: Extra checks compiled in for debug mode.
+Used in: Py_SAFE_DOWNCAST
+
+**************************************************************************/
+
+/* typedefs for some C9X-defined synonyms for integral types.
+ *
+ * The names in Python are exactly the same as the C9X names, except with a
+ * Py_ prefix. Until C9X is universally implemented, this is the only way
+ * to ensure that Python gets reliable names that don't conflict with names
+ * in non-Python code that are playing their own tricks to define the C9X
+ * names.
+ *
+ * NOTE: don't go nuts here! Python has no use for *most* of the C9X
+ * integral synonyms. Only define the ones we actually need.
+ */
+
+/* long long is required. Ensure HAVE_LONG_LONG is defined for compatibility. */
+#ifndef HAVE_LONG_LONG
+#define HAVE_LONG_LONG 1
+#endif
+#ifndef PY_LONG_LONG
+#define PY_LONG_LONG long long
+/* If LLONG_MAX is defined in limits.h, use that. */
+#define PY_LLONG_MIN LLONG_MIN
+#define PY_LLONG_MAX LLONG_MAX
+#define PY_ULLONG_MAX ULLONG_MAX
+#endif
+
+#define PY_UINT32_T uint32_t
+#define PY_UINT64_T uint64_t
+
+/* Signed variants of the above */
+#define PY_INT32_T int32_t
+#define PY_INT64_T int64_t
+
+/* If PYLONG_BITS_IN_DIGIT is not defined then we'll use 30-bit digits if all
+ the necessary integer types are available, and we're on a 64-bit platform
+ (as determined by SIZEOF_VOID_P); otherwise we use 15-bit digits. */
+
+#ifndef PYLONG_BITS_IN_DIGIT
+#if SIZEOF_VOID_P >= 8
+#define PYLONG_BITS_IN_DIGIT 30
+#else
+#define PYLONG_BITS_IN_DIGIT 15
+#endif
+#endif
+
+/* uintptr_t is the C9X name for an unsigned integral type such that a
+ * legitimate void* can be cast to uintptr_t and then back to void* again
+ * without loss of information. Similarly for intptr_t, wrt a signed
+ * integral type.
+ */
+typedef uintptr_t Py_uintptr_t;
+typedef intptr_t Py_intptr_t;
+
+/* Py_ssize_t is a signed integral type such that sizeof(Py_ssize_t) ==
+ * sizeof(size_t). C99 doesn't define such a thing directly (size_t is an
+ * unsigned integral type). See PEP 353 for details.
+ */
+#ifdef HAVE_SSIZE_T
+typedef ssize_t Py_ssize_t;
+#elif SIZEOF_VOID_P == SIZEOF_SIZE_T
+typedef Py_intptr_t Py_ssize_t;
+#else
+# error "Python needs a typedef for Py_ssize_t in pyport.h."
+#endif
+
+/* Py_hash_t is the same size as a pointer. */
+#define SIZEOF_PY_HASH_T SIZEOF_SIZE_T
+typedef Py_ssize_t Py_hash_t;
+/* Py_uhash_t is the unsigned equivalent needed to calculate numeric hash. */
+#define SIZEOF_PY_UHASH_T SIZEOF_SIZE_T
+typedef size_t Py_uhash_t;
+
+/* Only used for compatibility with code that may not be PY_SSIZE_T_CLEAN. */
+#ifdef PY_SSIZE_T_CLEAN
+typedef Py_ssize_t Py_ssize_clean_t;
+#else
+typedef int Py_ssize_clean_t;
+#endif
+
+/* Largest possible value of size_t. */
+#define PY_SIZE_MAX SIZE_MAX
+
+/* Largest positive value of type Py_ssize_t. */
+#define PY_SSIZE_T_MAX ((Py_ssize_t)(((size_t)-1)>>1))
+/* Smallest negative value of type Py_ssize_t. */
+#define PY_SSIZE_T_MIN (-PY_SSIZE_T_MAX-1)
+
+/* PY_FORMAT_SIZE_T is a platform-specific modifier for use in a printf
+ * format to convert an argument with the width of a size_t or Py_ssize_t.
+ * C99 introduced "z" for this purpose, but not all platforms support that;
+ * e.g., MS compilers use "I" instead.
+ *
+ * These "high level" Python format functions interpret "z" correctly on
+ * all platforms (Python interprets the format string itself, and does whatever
+ * the platform C requires to convert a size_t/Py_ssize_t argument):
+ *
+ * PyBytes_FromFormat
+ * PyErr_Format
+ * PyBytes_FromFormatV
+ * PyUnicode_FromFormatV
+ *
+ * Lower-level uses require that you interpolate the correct format modifier
+ * yourself (e.g., calling printf, fprintf, sprintf, PyOS_snprintf); for
+ * example,
+ *
+ * Py_ssize_t index;
+ * fprintf(stderr, "index %" PY_FORMAT_SIZE_T "d sucks\n", index);
+ *
+ * That will expand to %ld, or %Id, or to something else correct for a
+ * Py_ssize_t on the platform.
+ */
+#ifndef PY_FORMAT_SIZE_T
+# if SIZEOF_SIZE_T == SIZEOF_INT && !defined(__APPLE__)
+# define PY_FORMAT_SIZE_T ""
+# elif SIZEOF_SIZE_T == SIZEOF_LONG
+# define PY_FORMAT_SIZE_T "l"
+# elif defined(MS_WINDOWS)
+# define PY_FORMAT_SIZE_T "I"
+# else
+# error "This platform's pyconfig.h needs to define PY_FORMAT_SIZE_T"
+# endif
+#endif
+
+/* Py_LOCAL can be used instead of static to get the fastest possible calling
+ * convention for functions that are local to a given module.
+ *
+ * Py_LOCAL_INLINE does the same thing, and also explicitly requests inlining,
+ * for platforms that support that.
+ *
+ * If PY_LOCAL_AGGRESSIVE is defined before python.h is included, more
+ * "aggressive" inlining/optimization is enabled for the entire module. This
+ * may lead to code bloat, and may slow things down for those reasons. It may
+ * also lead to errors, if the code relies on pointer aliasing. Use with
+ * care.
+ *
+ * NOTE: You can only use this for functions that are entirely local to a
+ * module; functions that are exported via method tables, callbacks, etc,
+ * should keep using static.
+ */
+
+#if defined(_MSC_VER)
+#if defined(PY_LOCAL_AGGRESSIVE)
+/* enable more aggressive optimization for visual studio */
+#ifdef UEFI_C_SOURCE
+#pragma optimize("gt", on)
+#else
+#pragma optimize("agtw", on)
+#endif
+#endif
+/* ignore warnings if the compiler decides not to inline a function */
+#pragma warning(disable: 4710)
+/* fastest possible local call under MSVC */
+#define Py_LOCAL(type) static type __fastcall
+#define Py_LOCAL_INLINE(type) static __inline type __fastcall
+#elif defined(USE_INLINE)
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static inline type
+#else
+#define Py_LOCAL(type) static type
+#define Py_LOCAL_INLINE(type) static type
+#endif
+
+/* Py_MEMCPY is kept for backwards compatibility,
+ * see https://bugs.python.org/issue28126 */
+#define Py_MEMCPY memcpy
+
+#include <stdlib.h>
+
+#ifdef HAVE_IEEEFP_H
+#include <ieeefp.h> /* needed for 'finite' declaration on some platforms */
+#endif
+
+#include <math.h> /* Moved here from the math section, before extern "C" */
+
+/********************************************
+ * WRAPPER FOR <time.h> and/or <sys/time.h> *
+ ********************************************/
+
+#ifdef TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#else /* !TIME_WITH_SYS_TIME */
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else /* !HAVE_SYS_TIME_H */
+#include <time.h>
+#endif /* !HAVE_SYS_TIME_H */
+#endif /* !TIME_WITH_SYS_TIME */
+
+
+/******************************
+ * WRAPPER FOR <sys/select.h> *
+ ******************************/
+
+/* NB caller must include <sys/types.h> */
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* !HAVE_SYS_SELECT_H */
+
+/*******************************
+ * stat() and fstat() fiddling *
+ *******************************/
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#elif defined(HAVE_STAT_H)
+#include <stat.h>
+#endif
+
+#ifndef S_IFMT
+/* VisualAge C/C++ Failed to Define MountType Field in sys/stat.h */
+#define S_IFMT 0170000
+#endif
+
+#ifndef S_IFLNK
+/* Windows doesn't define S_IFLNK but posixmodule.c maps
+ * IO_REPARSE_TAG_SYMLINK to S_IFLNK */
+# define S_IFLNK 0120000
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
+#endif
+
+#ifndef S_ISDIR
+#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
+#endif
+
+#ifndef S_ISCHR
+#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR)
+#endif
+
+#ifdef __cplusplus
+/* Move this down here since some C++ #include's don't like to be included
+ inside an extern "C" */
+extern "C" {
+#endif
+
+
+/* Py_ARITHMETIC_RIGHT_SHIFT
+ * C doesn't define whether a right-shift of a signed integer sign-extends
+ * or zero-fills. Here a macro to force sign extension:
+ * Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J)
+ * Return I >> J, forcing sign extension. Arithmetically, return the
+ * floor of I/2**J.
+ * Requirements:
+ * I should have signed integer type. In the terminology of C99, this can
+ * be either one of the five standard signed integer types (signed char,
+ * short, int, long, long long) or an extended signed integer type.
+ * J is an integer >= 0 and strictly less than the number of bits in the
+ * type of I (because C doesn't define what happens for J outside that
+ * range either).
+ * TYPE used to specify the type of I, but is now ignored. It's been left
+ * in for backwards compatibility with versions <= 2.6 or 3.0.
+ * Caution:
+ * I may be evaluated more than once.
+ */
+#ifdef SIGNED_RIGHT_SHIFT_ZERO_FILLS
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) \
+ ((I) < 0 ? -1-((-1-(I)) >> (J)) : (I) >> (J))
+#else
+#define Py_ARITHMETIC_RIGHT_SHIFT(TYPE, I, J) ((I) >> (J))
+#endif
+
+/* Py_FORCE_EXPANSION(X)
+ * "Simply" returns its argument. However, macro expansions within the
+ * argument are evaluated. This unfortunate trickery is needed to get
+ * token-pasting to work as desired in some cases.
+ */
+#define Py_FORCE_EXPANSION(X) X
+
+/* Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW)
+ * Cast VALUE to type NARROW from type WIDE. In Py_DEBUG mode, this
+ * assert-fails if any information is lost.
+ * Caution:
+ * VALUE may be evaluated more than once.
+ */
+#ifdef Py_DEBUG
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) \
+ (assert((WIDE)(NARROW)(VALUE) == (VALUE)), (NARROW)(VALUE))
+#else
+#define Py_SAFE_DOWNCAST(VALUE, WIDE, NARROW) (NARROW)(VALUE)
+#endif
+
+/* Py_SET_ERRNO_ON_MATH_ERROR(x)
+ * If a libm function did not set errno, but it looks like the result
+ * overflowed or not-a-number, set errno to ERANGE or EDOM. Set errno
+ * to 0 before calling a libm function, and invoke this macro after,
+ * passing the function result.
+ * Caution:
+ * This isn't reliable. See Py_OVERFLOWED comments.
+ * X is evaluated more than once.
+ */
+#if defined(__FreeBSD__) || defined(__OpenBSD__) || (defined(__hpux) && defined(__ia64))
+#define _Py_SET_EDOM_FOR_NAN(X) if (isnan(X)) errno = EDOM;
+#else
+#define _Py_SET_EDOM_FOR_NAN(X) ;
+#endif
+#define Py_SET_ERRNO_ON_MATH_ERROR(X) \
+ do { \
+ if (errno == 0) { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
+ errno = ERANGE; \
+ else _Py_SET_EDOM_FOR_NAN(X) \
+ } \
+ } while(0)
+
+/* Py_SET_ERANGE_ON_OVERFLOW(x)
+ * An alias of Py_SET_ERRNO_ON_MATH_ERROR for backward-compatibility.
+ */
+#define Py_SET_ERANGE_IF_OVERFLOW(X) Py_SET_ERRNO_ON_MATH_ERROR(X)
+
+/* Py_ADJUST_ERANGE1(x)
+ * Py_ADJUST_ERANGE2(x, y)
+ * Set errno to 0 before calling a libm function, and invoke one of these
+ * macros after, passing the function result(s) (Py_ADJUST_ERANGE2 is useful
+ * for functions returning complex results). This makes two kinds of
+ * adjustments to errno: (A) If it looks like the platform libm set
+ * errno=ERANGE due to underflow, clear errno. (B) If it looks like the
+ * platform libm overflowed but didn't set errno, force errno to ERANGE. In
+ * effect, we're trying to force a useful implementation of C89 errno
+ * behavior.
+ * Caution:
+ * This isn't reliable. See Py_OVERFLOWED comments.
+ * X and Y may be evaluated more than once.
+ */
+#define Py_ADJUST_ERANGE1(X) \
+ do { \
+ if (errno == 0) { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL) \
+ errno = ERANGE; \
+ } \
+ else if (errno == ERANGE && (X) == 0.0) \
+ errno = 0; \
+ } while(0)
+
+#define Py_ADJUST_ERANGE2(X, Y) \
+ do { \
+ if ((X) == Py_HUGE_VAL || (X) == -Py_HUGE_VAL || \
+ (Y) == Py_HUGE_VAL || (Y) == -Py_HUGE_VAL) { \
+ if (errno == 0) \
+ errno = ERANGE; \
+ } \
+ else if (errno == ERANGE) \
+ errno = 0; \
+ } while(0)
+
+/* The functions _Py_dg_strtod and _Py_dg_dtoa in Python/dtoa.c (which are
+ * required to support the short float repr introduced in Python 3.1) require
+ * that the floating-point unit that's being used for arithmetic operations
+ * on C doubles is set to use 53-bit precision. It also requires that the
+ * FPU rounding mode is round-half-to-even, but that's less often an issue.
+ *
+ * If your FPU isn't already set to 53-bit precision/round-half-to-even, and
+ * you want to make use of _Py_dg_strtod and _Py_dg_dtoa, then you should
+ *
+ * #define HAVE_PY_SET_53BIT_PRECISION 1
+ *
+ * and also give appropriate definitions for the following three macros:
+ *
+ * _PY_SET_53BIT_PRECISION_START : store original FPU settings, and
+ * set FPU to 53-bit precision/round-half-to-even
+ * _PY_SET_53BIT_PRECISION_END : restore original FPU settings
+ * _PY_SET_53BIT_PRECISION_HEADER : any variable declarations needed to
+ * use the two macros above.
+ *
+ * The macros are designed to be used within a single C function: see
+ * Python/pystrtod.c for an example of their use.
+ */
+
+/* get and set x87 control word for gcc/x86 */
+#ifdef HAVE_GCC_ASM_FOR_X87
+#define HAVE_PY_SET_53BIT_PRECISION 1
+/* _Py_get/set_387controlword functions are defined in Python/pymath.c */
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned short old_387controlword, new_387controlword
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ old_387controlword = _Py_get_387controlword(); \
+ new_387controlword = (old_387controlword & ~0x0f00) | 0x0200; \
+ if (new_387controlword != old_387controlword) \
+ _Py_set_387controlword(new_387controlword); \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ if (new_387controlword != old_387controlword) \
+ _Py_set_387controlword(old_387controlword)
+#endif
+
+/* get and set x87 control word for VisualStudio/x86 */
+#if defined(_MSC_VER) && !defined(_WIN64) && !defined(UEFI_C_SOURCE)/* x87 not supported in 64-bit */
+#define HAVE_PY_SET_53BIT_PRECISION 1
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned int old_387controlword, new_387controlword, out_387controlword
+/* We use the __control87_2 function to set only the x87 control word.
+ The SSE control word is unaffected. */
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ __control87_2(0, 0, &old_387controlword, NULL); \
+ new_387controlword = \
+ (old_387controlword & ~(_MCW_PC | _MCW_RC)) | (_PC_53 | _RC_NEAR); \
+ if (new_387controlword != old_387controlword) \
+ __control87_2(new_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ do { \
+ if (new_387controlword != old_387controlword) \
+ __control87_2(old_387controlword, _MCW_PC | _MCW_RC, \
+ &out_387controlword, NULL); \
+ } while (0)
+#endif
+
+#ifdef HAVE_GCC_ASM_FOR_MC68881
+#define HAVE_PY_SET_53BIT_PRECISION 1
+#define _Py_SET_53BIT_PRECISION_HEADER \
+ unsigned int old_fpcr, new_fpcr
+#define _Py_SET_53BIT_PRECISION_START \
+ do { \
+ __asm__ ("fmove.l %%fpcr,%0" : "=g" (old_fpcr)); \
+ /* Set double precision / round to nearest. */ \
+ new_fpcr = (old_fpcr & ~0xf0) | 0x80; \
+ if (new_fpcr != old_fpcr) \
+ __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (new_fpcr)); \
+ } while (0)
+#define _Py_SET_53BIT_PRECISION_END \
+ do { \
+ if (new_fpcr != old_fpcr) \
+ __asm__ volatile ("fmove.l %0,%%fpcr" : : "g" (old_fpcr)); \
+ } while (0)
+#endif
+
+/* default definitions are empty */
+#ifndef HAVE_PY_SET_53BIT_PRECISION
+#define _Py_SET_53BIT_PRECISION_HEADER
+#define _Py_SET_53BIT_PRECISION_START
+#define _Py_SET_53BIT_PRECISION_END
+#endif
+
+/* If we can't guarantee 53-bit precision, don't use the code
+ in Python/dtoa.c, but fall back to standard code. This
+ means that repr of a float will be long (17 sig digits).
+
+ Realistically, there are two things that could go wrong:
+
+ (1) doubles aren't IEEE 754 doubles, or
+ (2) we're on x86 with the rounding precision set to 64-bits
+ (extended precision), and we don't know how to change
+ the rounding precision.
+ */
+
+#if !defined(DOUBLE_IS_LITTLE_ENDIAN_IEEE754) && \
+ !defined(DOUBLE_IS_BIG_ENDIAN_IEEE754) && \
+ !defined(DOUBLE_IS_ARM_MIXED_ENDIAN_IEEE754)
+#define PY_NO_SHORT_FLOAT_REPR
+#endif
+
+/* double rounding is symptomatic of use of extended precision on x86. If
+ we're seeing double rounding, and we don't have any mechanism available for
+ changing the FPU rounding precision, then don't use Python/dtoa.c. */
+#if defined(X87_DOUBLE_ROUNDING) && !defined(HAVE_PY_SET_53BIT_PRECISION)
+#define PY_NO_SHORT_FLOAT_REPR
+#endif
+
+
+/* Py_DEPRECATED(version)
+ * Declare a variable, type, or function deprecated.
+ * Usage:
+ * extern int old_var Py_DEPRECATED(2.3);
+ * typedef int T1 Py_DEPRECATED(2.4);
+ * extern int x() Py_DEPRECATED(2.5);
+ */
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || \
+ (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
+#define Py_DEPRECATED(VERSION_UNUSED) __attribute__((__deprecated__))
+#else
+#define Py_DEPRECATED(VERSION_UNUSED)
+#endif
+
+/**************************************************************************
+Prototypes that are missing from the standard include files on some systems
+(and possibly only some versions of such systems.)
+
+Please be conservative with adding new ones, document them and enclose them
+in platform-specific #ifdefs.
+**************************************************************************/
+
+#ifdef SOLARIS
+/* Unchecked */
+extern int gethostname(char *, int);
+#endif
+
+#ifdef HAVE__GETPTY
+#include <sys/types.h> /* we need to import mode_t */
+extern char * _getpty(int *, int, mode_t, int);
+#endif
+
+/* On QNX 6, struct termio must be declared by including sys/termio.h
+ if TCGETA, TCSETA, TCSETAW, or TCSETAF are used. sys/termio.h must
+ be included before termios.h or it will generate an error. */
+#if defined(HAVE_SYS_TERMIO_H) && !defined(__hpux)
+#include <sys/termio.h>
+#endif
+
+#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY)
+#if !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H)
+/* BSDI does not supply a prototype for the 'openpty' and 'forkpty'
+ functions, even though they are included in libutil. */
+#include <termios.h>
+extern int openpty(int *, int *, char *, struct termios *, struct winsize *);
+extern pid_t forkpty(int *, char *, struct termios *, struct winsize *);
+#endif /* !defined(HAVE_PTY_H) && !defined(HAVE_LIBUTIL_H) */
+#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */
+
+
+/* On 4.4BSD-descendants, ctype functions serves the whole range of
+ * wchar_t character set rather than single byte code points only.
+ * This characteristic can break some operations of string object
+ * including str.upper() and str.split() on UTF-8 locales. This
+ * workaround was provided by Tim Robbins of FreeBSD project.
+ */
+
+#ifdef __FreeBSD__
+#include <osreldate.h>
+#if (__FreeBSD_version >= 500040 && __FreeBSD_version < 602113) || \
+ (__FreeBSD_version >= 700000 && __FreeBSD_version < 700054) || \
+ (__FreeBSD_version >= 800000 && __FreeBSD_version < 800001)
+# define _PY_PORT_CTYPE_UTF8_ISSUE
+#endif
+#endif
+
+
+#if defined(__APPLE__)
+# define _PY_PORT_CTYPE_UTF8_ISSUE
+#endif
+
+#ifdef _PY_PORT_CTYPE_UTF8_ISSUE
+#ifndef __cplusplus
+ /* The workaround below is unsafe in C++ because
+ * the <locale> defines these symbols as real functions,
+ * with a slightly different signature.
+ * See issue #10910
+ */
+#include <ctype.h>
+#include <wctype.h>
+#undef isalnum
+#define isalnum(c) iswalnum(btowc(c))
+#undef isalpha
+#define isalpha(c) iswalpha(btowc(c))
+#undef islower
+#define islower(c) iswlower(btowc(c))
+#undef isspace
+#define isspace(c) iswspace(btowc(c))
+#undef isupper
+#define isupper(c) iswupper(btowc(c))
+#undef tolower
+#define tolower(c) towlower(btowc(c))
+#undef toupper
+#define toupper(c) towupper(btowc(c))
+#endif
+#endif
+
+
+/* Declarations for symbol visibility.
+
+ PyAPI_FUNC(type): Declares a public Python API function and return type
+ PyAPI_DATA(type): Declares public Python data and its type
+ PyMODINIT_FUNC: A Python module init function. If these functions are
+ inside the Python core, they are private to the core.
+ If in an extension module, it may be declared with
+ external linkage depending on the platform.
+
+ As a number of platforms support/require "__declspec(dllimport/dllexport)",
+ we support a HAVE_DECLSPEC_DLL macro to save duplication.
+*/
+
+/*
+ All windows ports, except cygwin, are handled in PC/pyconfig.h.
+
+ Cygwin is the only other autoconf platform requiring special
+ linkage handling and it uses __declspec().
+*/
+#if defined(__CYGWIN__)
+# define HAVE_DECLSPEC_DLL
+#endif
+
+/* only get special linkage if built as shared or platform is Cygwin */
+#if defined(Py_ENABLE_SHARED) || defined(__CYGWIN__)
+# if defined(HAVE_DECLSPEC_DLL)
+# ifdef Py_BUILD_CORE
+# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
+# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
+ /* module init functions inside the core need no external linkage */
+ /* except for Cygwin to handle embedding */
+# if defined(__CYGWIN__)
+# define PyMODINIT_FUNC __declspec(dllexport) PyObject*
+# else /* __CYGWIN__ */
+# define PyMODINIT_FUNC PyObject*
+# endif /* __CYGWIN__ */
+# else /* Py_BUILD_CORE */
+ /* Building an extension module, or an embedded situation */
+ /* public Python functions and data are imported */
+ /* Under Cygwin, auto-import functions to prevent compilation */
+ /* failures similar to those described at the bottom of 4.1: */
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
+# if !defined(__CYGWIN__)
+# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
+# endif /* !__CYGWIN__ */
+# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
+ /* module init functions outside the core must be exported */
+# if defined(__cplusplus)
+# define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject*
+# else /* __cplusplus */
+# define PyMODINIT_FUNC __declspec(dllexport) PyObject*
+# endif /* __cplusplus */
+# endif /* Py_BUILD_CORE */
+# endif /* HAVE_DECLSPEC */
+#endif /* Py_ENABLE_SHARED */
+
+/* If no external linkage macros defined by now, create defaults */
+#ifndef PyAPI_FUNC
+# define PyAPI_FUNC(RTYPE) RTYPE
+#endif
+#ifndef PyAPI_DATA
+# define PyAPI_DATA(RTYPE) extern RTYPE
+#endif
+#ifndef PyMODINIT_FUNC
+# if defined(__cplusplus)
+# define PyMODINIT_FUNC extern "C" PyObject*
+# else /* __cplusplus */
+# define PyMODINIT_FUNC PyObject*
+# endif /* __cplusplus */
+#endif
+
+/* limits.h constants that may be missing */
+
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+
+#ifndef LONG_MAX
+#if SIZEOF_LONG == 4
+#define LONG_MAX 0X7FFFFFFFL
+#elif SIZEOF_LONG == 8
+#define LONG_MAX 0X7FFFFFFFFFFFFFFFL
+#else
+#error "could not set LONG_MAX in pyport.h"
+#endif
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX-1)
+#endif
+
+#ifndef LONG_BIT
+#define LONG_BIT (8 * SIZEOF_LONG)
+#endif
+
+#if LONG_BIT != 8 * SIZEOF_LONG
+/* 04-Oct-2000 LONG_BIT is apparently (mis)defined as 64 on some recent
+ * 32-bit platforms using gcc. We try to catch that here at compile-time
+ * rather than waiting for integer multiplication to trigger bogus
+ * overflows.
+ */
+#error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)."
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ * Hide GCC attributes from compilers that don't support them.
+ */
+#if (!defined(__GNUC__) || __GNUC__ < 2 || \
+ (__GNUC__ == 2 && __GNUC_MINOR__ < 7) )
+#define Py_GCC_ATTRIBUTE(x)
+#else
+#define Py_GCC_ATTRIBUTE(x) __attribute__(x)
+#endif
+
+/*
+ * Specify alignment on compilers that support it.
+ */
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define Py_ALIGNED(x) __attribute__((aligned(x)))
+#else
+#define Py_ALIGNED(x)
+#endif
+
+/* Eliminate end-of-loop code not reached warnings from SunPro C
+ * when using do{...}while(0) macros
+ */
+#ifdef __SUNPRO_C
+#pragma error_messages (off,E_END_OF_LOOP_CODE_NOT_REACHED)
+#endif
+
+#ifndef Py_LL
+#define Py_LL(x) x##LL
+#endif
+
+#ifndef Py_ULL
+#define Py_ULL(x) Py_LL(x##U)
+#endif
+
+#define Py_VA_COPY va_copy
+
+/*
+ * Convenient macros to deal with endianness of the platform. WORDS_BIGENDIAN is
+ * detected by configure and defined in pyconfig.h. The code in pyconfig.h
+ * also takes care of Apple's universal builds.
+ */
+
+#ifdef WORDS_BIGENDIAN
+#define PY_BIG_ENDIAN 1
+#define PY_LITTLE_ENDIAN 0
+#else
+#define PY_BIG_ENDIAN 0
+#define PY_LITTLE_ENDIAN 1
+#endif
+
+#ifdef Py_BUILD_CORE
+/*
+ * Macros to protect CRT calls against instant termination when passed an
+ * invalid parameter (issue23524).
+ */
+#if defined _MSC_VER && _MSC_VER >= 1900 && !defined(UEFI_C_SOURCE)
+
+extern _invalid_parameter_handler _Py_silent_invalid_parameter_handler;
+#define _Py_BEGIN_SUPPRESS_IPH { _invalid_parameter_handler _Py_old_handler = \
+ _set_thread_local_invalid_parameter_handler(_Py_silent_invalid_parameter_handler);
+#define _Py_END_SUPPRESS_IPH _set_thread_local_invalid_parameter_handler(_Py_old_handler); }
+
+#else
+
+#define _Py_BEGIN_SUPPRESS_IPH
+#define _Py_END_SUPPRESS_IPH
+
+#endif /* _MSC_VER >= 1900 */
+#endif /* Py_BUILD_CORE */
+
+#ifdef UEFI_C_SOURCE
+#define _Py_BEGIN_SUPPRESS_IPH
+#define _Py_END_SUPPRESS_IPH
+#endif
+
+#ifdef __ANDROID__
+#include <android/api-level.h>
+#endif
+
+#endif /* Py_PYPORT_H */
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ctypes/__init__.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ctypes/__init__.py
new file mode 100644
index 00000000..07fb8bda
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ctypes/__init__.py
@@ -0,0 +1,549 @@
+# Create and manipulate C data types in Python
+#
+# Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+import os as _os, sys as _sys
+
+__version__ = "1.1.0"
+
+from _ctypes import Union, Structure, Array
+from _ctypes import _Pointer
+from _ctypes import CFuncPtr as _CFuncPtr
+from _ctypes import __version__ as _ctypes_version
+from _ctypes import RTLD_LOCAL, RTLD_GLOBAL
+from _ctypes import ArgumentError
+
+from struct import calcsize as _calcsize
+
+if __version__ != _ctypes_version:
+ raise Exception("Version number mismatch", __version__, _ctypes_version)
+
+if _os.name == "nt":
+ from _ctypes import FormatError
+
+DEFAULT_MODE = RTLD_LOCAL
+if _os.name == "posix" and _sys.platform == "darwin":
+ # On OS X 10.3, we use RTLD_GLOBAL as default mode
+ # because RTLD_LOCAL does not work at least on some
+ # libraries. OS X 10.3 is Darwin 7, so we check for
+ # that.
+
+ if int(_os.uname().release.split('.')[0]) < 8:
+ DEFAULT_MODE = RTLD_GLOBAL
+
+from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \
+ FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \
+ FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \
+ FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR
+
+# WINOLEAPI -> HRESULT
+# WINOLEAPI_(type)
+#
+# STDMETHODCALLTYPE
+#
+# STDMETHOD(name)
+# STDMETHOD_(type, name)
+#
+# STDAPICALLTYPE
+
+def create_string_buffer(init, size=None):
+ """create_string_buffer(aBytes) -> character array
+ create_string_buffer(anInteger) -> character array
+ create_string_buffer(aBytes, anInteger) -> character array
+ """
+ if isinstance(init, bytes):
+ if size is None:
+ size = len(init)+1
+ buftype = c_char * size
+ buf = buftype()
+ buf.value = init
+ return buf
+ elif isinstance(init, int):
+ buftype = c_char * init
+ buf = buftype()
+ return buf
+ raise TypeError(init)
+
+def c_buffer(init, size=None):
+## "deprecated, use create_string_buffer instead"
+## import warnings
+## warnings.warn("c_buffer is deprecated, use create_string_buffer instead",
+## DeprecationWarning, stacklevel=2)
+ return create_string_buffer(init, size)
+
+_c_functype_cache = {}
+def CFUNCTYPE(restype, *argtypes, **kw):
+ """CFUNCTYPE(restype, *argtypes,
+ use_errno=False, use_last_error=False) -> function prototype.
+
+ restype: the result type
+ argtypes: a sequence specifying the argument types
+
+ The function prototype can be called in different ways to create a
+ callable object:
+
+ prototype(integer address) -> foreign function
+ prototype(callable) -> create and return a C callable function from callable
+ prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method
+ prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal
+ prototype((function name, dll object)[, paramflags]) -> foreign function exported by name
+ """
+ flags = _FUNCFLAG_CDECL
+ if kw.pop("use_errno", False):
+ flags |= _FUNCFLAG_USE_ERRNO
+ if kw.pop("use_last_error", False):
+ flags |= _FUNCFLAG_USE_LASTERROR
+ if kw:
+ raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
+ try:
+ return _c_functype_cache[(restype, argtypes, flags)]
+ except KeyError:
+ class CFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = flags
+ _c_functype_cache[(restype, argtypes, flags)] = CFunctionType
+ return CFunctionType
+
+if _os.name == "nt":
+ from _ctypes import LoadLibrary as _dlopen
+ from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL
+
+ _win_functype_cache = {}
+ def WINFUNCTYPE(restype, *argtypes, **kw):
+ # docstring set later (very similar to CFUNCTYPE.__doc__)
+ flags = _FUNCFLAG_STDCALL
+ if kw.pop("use_errno", False):
+ flags |= _FUNCFLAG_USE_ERRNO
+ if kw.pop("use_last_error", False):
+ flags |= _FUNCFLAG_USE_LASTERROR
+ if kw:
+ raise ValueError("unexpected keyword argument(s) %s" % kw.keys())
+ try:
+ return _win_functype_cache[(restype, argtypes, flags)]
+ except KeyError:
+ class WinFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = flags
+ _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType
+ return WinFunctionType
+ if WINFUNCTYPE.__doc__:
+ WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE")
+
+elif _os.name == "posix":
+ from _ctypes import dlopen as _dlopen
+
+from _ctypes import sizeof, byref, addressof, alignment, resize
+from _ctypes import get_errno, set_errno
+from _ctypes import _SimpleCData
+
+def _check_size(typ, typecode=None):
+ # Check if sizeof(ctypes_type) against struct.calcsize. This
+ # should protect somewhat against a misconfigured libffi.
+ from struct import calcsize
+ if typecode is None:
+ # Most _type_ codes are the same as used in struct
+ typecode = typ._type_
+ actual, required = sizeof(typ), calcsize(typecode)
+ if actual != required:
+ raise SystemError("sizeof(%s) wrong: %d instead of %d" % \
+ (typ, actual, required))
+
+class py_object(_SimpleCData):
+ _type_ = "O"
+ def __repr__(self):
+ try:
+ return super().__repr__()
+ except ValueError:
+ return "%s(<NULL>)" % type(self).__name__
+_check_size(py_object, "P")
+
+class c_short(_SimpleCData):
+ _type_ = "h"
+_check_size(c_short)
+
+class c_ushort(_SimpleCData):
+ _type_ = "H"
+_check_size(c_ushort)
+
+class c_long(_SimpleCData):
+ _type_ = "l"
+_check_size(c_long)
+
+class c_ulong(_SimpleCData):
+ _type_ = "L"
+_check_size(c_ulong)
+
+if _calcsize("i") == _calcsize("l"):
+ # if int and long have the same size, make c_int an alias for c_long
+ c_int = c_long
+ c_uint = c_ulong
+else:
+ class c_int(_SimpleCData):
+ _type_ = "i"
+ _check_size(c_int)
+
+ class c_uint(_SimpleCData):
+ _type_ = "I"
+ _check_size(c_uint)
+
+class c_float(_SimpleCData):
+ _type_ = "f"
+_check_size(c_float)
+
+class c_double(_SimpleCData):
+ _type_ = "d"
+_check_size(c_double)
+
+class c_longdouble(_SimpleCData):
+ _type_ = "g"
+if sizeof(c_longdouble) == sizeof(c_double):
+ c_longdouble = c_double
+
+if _calcsize("l") == _calcsize("q"):
+ # if long and long long have the same size, make c_longlong an alias for c_long
+ c_longlong = c_long
+ c_ulonglong = c_ulong
+else:
+ class c_longlong(_SimpleCData):
+ _type_ = "q"
+ _check_size(c_longlong)
+
+ class c_ulonglong(_SimpleCData):
+ _type_ = "Q"
+ ## def from_param(cls, val):
+ ## return ('d', float(val), val)
+ ## from_param = classmethod(from_param)
+ _check_size(c_ulonglong)
+
+class c_ubyte(_SimpleCData):
+ _type_ = "B"
+c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte
+# backward compatibility:
+##c_uchar = c_ubyte
+_check_size(c_ubyte)
+
+class c_byte(_SimpleCData):
+ _type_ = "b"
+c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte
+_check_size(c_byte)
+
+class c_char(_SimpleCData):
+ _type_ = "c"
+c_char.__ctype_le__ = c_char.__ctype_be__ = c_char
+_check_size(c_char)
+
+class c_char_p(_SimpleCData):
+ _type_ = "z"
+ def __repr__(self):
+ return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
+_check_size(c_char_p, "P")
+
+class c_void_p(_SimpleCData):
+ _type_ = "P"
+c_voidp = c_void_p # backwards compatibility (to a bug)
+_check_size(c_void_p)
+
+class c_bool(_SimpleCData):
+ _type_ = "?"
+
+from _ctypes import POINTER, pointer, _pointer_type_cache
+
+class c_wchar_p(_SimpleCData):
+ _type_ = "Z"
+ def __repr__(self):
+ return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value)
+
+class c_wchar(_SimpleCData):
+ _type_ = "u"
+
+def _reset_cache():
+ _pointer_type_cache.clear()
+ _c_functype_cache.clear()
+ if _os.name == "nt":
+ _win_functype_cache.clear()
+ # _SimpleCData.c_wchar_p_from_param
+ POINTER(c_wchar).from_param = c_wchar_p.from_param
+ # _SimpleCData.c_char_p_from_param
+ POINTER(c_char).from_param = c_char_p.from_param
+ _pointer_type_cache[None] = c_void_p
+ # XXX for whatever reasons, creating the first instance of a callback
+ # function is needed for the unittests on Win64 to succeed. This MAY
+ # be a compiler bug, since the problem occurs only when _ctypes is
+ # compiled with the MS SDK compiler. Or an uninitialized variable?
+ CFUNCTYPE(c_int)(lambda: None)
+
+def create_unicode_buffer(init, size=None):
+ """create_unicode_buffer(aString) -> character array
+ create_unicode_buffer(anInteger) -> character array
+ create_unicode_buffer(aString, anInteger) -> character array
+ """
+ if isinstance(init, str):
+ if size is None:
+ size = len(init)+1
+ buftype = c_wchar * size
+ buf = buftype()
+ buf.value = init
+ return buf
+ elif isinstance(init, int):
+ buftype = c_wchar * init
+ buf = buftype()
+ return buf
+ raise TypeError(init)
+
+
+# XXX Deprecated
+def SetPointerType(pointer, cls):
+ if _pointer_type_cache.get(cls, None) is not None:
+ raise RuntimeError("This type already exists in the cache")
+ if id(pointer) not in _pointer_type_cache:
+ raise RuntimeError("What's this???")
+ pointer.set_type(cls)
+ _pointer_type_cache[cls] = pointer
+ del _pointer_type_cache[id(pointer)]
+
+# XXX Deprecated
+def ARRAY(typ, len):
+ return typ * len
+
+################################################################
+
+
+if _os.name != "edk2":
+ class CDLL(object):
+ """An instance of this class represents a loaded dll/shared
+ library, exporting functions using the standard C calling
+ convention (named 'cdecl' on Windows).
+
+ The exported functions can be accessed as attributes, or by
+ indexing with the function name. Examples:
+
+ <obj>.qsort -> callable object
+ <obj>['qsort'] -> callable object
+
+ Calling the functions releases the Python GIL during the call and
+ reacquires it afterwards.
+ """
+ _func_flags_ = _FUNCFLAG_CDECL
+ _func_restype_ = c_int
+ # default values for repr
+ _name = '<uninitialized>'
+ _handle = 0
+ _FuncPtr = None
+
+ def __init__(self, name, mode=DEFAULT_MODE, handle=None,
+ use_errno=False,
+ use_last_error=False):
+ self._name = name
+ flags = self._func_flags_
+ if use_errno:
+ flags |= _FUNCFLAG_USE_ERRNO
+ if use_last_error:
+ flags |= _FUNCFLAG_USE_LASTERROR
+
+ class _FuncPtr(_CFuncPtr):
+ _flags_ = flags
+ _restype_ = self._func_restype_
+ self._FuncPtr = _FuncPtr
+
+ if handle is None:
+ self._handle = _dlopen(self._name, mode)
+ else:
+ self._handle = handle
+
+ def __repr__(self):
+ return "<%s '%s', handle %x at %#x>" % \
+ (self.__class__.__name__, self._name,
+ (self._handle & (_sys.maxsize*2 + 1)),
+ id(self) & (_sys.maxsize*2 + 1))
+
+ def __getattr__(self, name):
+ if name.startswith('__') and name.endswith('__'):
+ raise AttributeError(name)
+ func = self.__getitem__(name)
+ setattr(self, name, func)
+ return func
+
+ def __getitem__(self, name_or_ordinal):
+ func = self._FuncPtr((name_or_ordinal, self))
+ if not isinstance(name_or_ordinal, int):
+ func.__name__ = name_or_ordinal
+ return func
+
+ class PyDLL(CDLL):
+ """This class represents the Python library itself. It allows to
+ access Python API functions. The GIL is not released, and
+ Python exceptions are handled correctly.
+ """
+ _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+
+if _os.name == "nt":
+
+ class WinDLL(CDLL):
+ """This class represents a dll exporting functions using the
+ Windows stdcall calling convention.
+ """
+ _func_flags_ = _FUNCFLAG_STDCALL
+
+ # XXX Hm, what about HRESULT as normal parameter?
+ # Mustn't it derive from c_long then?
+ from _ctypes import _check_HRESULT, _SimpleCData
+ class HRESULT(_SimpleCData):
+ _type_ = "l"
+ # _check_retval_ is called with the function's result when it
+ # is used as restype. It checks for the FAILED bit, and
+ # raises an OSError if it is set.
+ #
+ # The _check_retval_ method is implemented in C, so that the
+ # method definition itself is not included in the traceback
+ # when it raises an error - that is what we want (and Python
+ # doesn't have a way to raise an exception in the caller's
+ # frame).
+ _check_retval_ = _check_HRESULT
+
+ class OleDLL(CDLL):
+ """This class represents a dll exporting functions using the
+ Windows stdcall calling convention, and returning HRESULT.
+ HRESULT error values are automatically raised as OSError
+ exceptions.
+ """
+ _func_flags_ = _FUNCFLAG_STDCALL
+ _func_restype_ = HRESULT
+
+if _os.name != "edk2":
+ class LibraryLoader(object):
+ def __init__(self, dlltype):
+ self._dlltype = dlltype
+
+ def __getattr__(self, name):
+ if name[0] == '_':
+ raise AttributeError(name)
+ dll = self._dlltype(name)
+ setattr(self, name, dll)
+ return dll
+
+ def __getitem__(self, name):
+ return getattr(self, name)
+
+ def LoadLibrary(self, name):
+ return self._dlltype(name)
+
+ cdll = LibraryLoader(CDLL)
+ pydll = LibraryLoader(PyDLL)
+
+ if _os.name == "nt":
+ pythonapi = PyDLL("python dll", None, _sys.dllhandle)
+ elif _sys.platform == "cygwin":
+ pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2])
+ else:
+ pythonapi = PyDLL(None)
+
+
+if _os.name == "nt":
+ windll = LibraryLoader(WinDLL)
+ oledll = LibraryLoader(OleDLL)
+
+ if _os.name == "nt":
+ GetLastError = windll.kernel32.GetLastError
+ else:
+ GetLastError = windll.coredll.GetLastError
+ from _ctypes import get_last_error, set_last_error
+
+ def WinError(code=None, descr=None):
+ if code is None:
+ code = GetLastError()
+ if descr is None:
+ descr = FormatError(code).strip()
+ return OSError(None, descr, None, code)
+
+if sizeof(c_uint) == sizeof(c_void_p):
+ c_size_t = c_uint
+ c_ssize_t = c_int
+elif sizeof(c_ulong) == sizeof(c_void_p):
+ c_size_t = c_ulong
+ c_ssize_t = c_long
+elif sizeof(c_ulonglong) == sizeof(c_void_p):
+ c_size_t = c_ulonglong
+ c_ssize_t = c_longlong
+
+# functions
+
+from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr
+
+## void *memmove(void *, const void *, size_t);
+memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr)
+
+## void *memset(void *, int, size_t)
+memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr)
+
+def PYFUNCTYPE(restype, *argtypes):
+ class CFunctionType(_CFuncPtr):
+ _argtypes_ = argtypes
+ _restype_ = restype
+ _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI
+ return CFunctionType
+
+_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr)
+def cast(obj, typ):
+ return _cast(obj, obj, typ)
+
+_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr)
+def string_at(ptr, size=-1):
+ """string_at(addr[, size]) -> string
+
+ Return the string at addr."""
+ return _string_at(ptr, size)
+
+try:
+ from _ctypes import _wstring_at_addr
+except ImportError:
+ pass
+else:
+ _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr)
+ def wstring_at(ptr, size=-1):
+ """wstring_at(addr[, size]) -> string
+
+ Return the string at addr."""
+ return _wstring_at(ptr, size)
+
+
+if _os.name == "nt": # COM stuff
+ def DllGetClassObject(rclsid, riid, ppv):
+ try:
+ ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
+ except ImportError:
+ return -2147221231 # CLASS_E_CLASSNOTAVAILABLE
+ else:
+ return ccom.DllGetClassObject(rclsid, riid, ppv)
+
+ def DllCanUnloadNow():
+ try:
+ ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*'])
+ except ImportError:
+ return 0 # S_OK
+ return ccom.DllCanUnloadNow()
+
+from ctypes._endian import BigEndianStructure, LittleEndianStructure
+
+# Fill in specifically-sized types
+c_int8 = c_byte
+c_uint8 = c_ubyte
+for kind in [c_short, c_int, c_long, c_longlong]:
+ if sizeof(kind) == 2: c_int16 = kind
+ elif sizeof(kind) == 4: c_int32 = kind
+ elif sizeof(kind) == 8: c_int64 = kind
+for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]:
+ if sizeof(kind) == 2: c_uint16 = kind
+ elif sizeof(kind) == 4: c_uint32 = kind
+ elif sizeof(kind) == 8: c_uint64 = kind
+del(kind)
+
+_reset_cache()
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/genericpath.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/genericpath.py
new file mode 100644
index 00000000..46b8c921
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/genericpath.py
@@ -0,0 +1,157 @@
+"""
+Path operations common to more than one OS
+Do not use directly. The OS specific modules import the appropriate
+functions from this module themselves.
+"""
+import os
+import stat
+
+# If Python is built without Unicode support, the unicode type
+# will not exist. Fake one.
+class _unicode(object):
+ pass
+
+
+__all__ = ['commonprefix', 'exists', 'getatime', 'getctime', 'getmtime',
+ 'getsize', 'isdir', 'isfile', 'samefile', 'sameopenfile',
+ 'samestat', '_unicode']
+
+
+# Does a path exist?
+# This is false for dangling symbolic links on systems that support them.
+def exists(path):
+ """Test whether a path exists. Returns False for broken symbolic links"""
+ try:
+ os.stat(path)
+ except OSError:
+ return False
+ return True
+
+
+# This follows symbolic links, so both islink() and isdir() can be true
+# for the same path on systems that support symlinks
+def isfile(path):
+ """Test whether a path is a regular file"""
+ try:
+ st = os.stat(path)
+ except OSError:
+ return False
+ return stat.S_ISREG(st.st_mode)
+
+
+# Is a path a directory?
+# This follows symbolic links, so both islink() and isdir()
+# can be true for the same path on systems that support symlinks
+def isdir(s):
+ """Return true if the pathname refers to an existing directory."""
+ try:
+ st = os.stat(s)
+ except OSError:
+ return False
+ return stat.S_ISDIR(st.st_mode)
+
+
+def getsize(filename):
+ """Return the size of a file, reported by os.stat()."""
+ return os.stat(filename).st_size
+
+
+def getmtime(filename):
+ """Return the last modification time of a file, reported by os.stat()."""
+ return os.stat(filename).st_mtime
+
+
+def getatime(filename):
+ """Return the last access time of a file, reported by os.stat()."""
+ return os.stat(filename).st_atime
+
+
+def getctime(filename):
+ """Return the metadata change time of a file, reported by os.stat()."""
+ return os.stat(filename).st_ctime
+
+
+# Return the longest prefix of all list elements.
+def commonprefix(m):
+ "Given a list of pathnames, returns the longest common leading component"
+ if not m: return ''
+ # Some people pass in a list of pathname parts to operate in an OS-agnostic
+ # fashion; don't try to translate in that case as that's an abuse of the
+ # API and they are already doing what they need to be OS-agnostic and so
+ # they most likely won't be using an os.PathLike object in the sublists.
+ if not isinstance(m[0], (list, tuple)):
+ m = tuple(map(os.fspath, m))
+ s1 = min(m)
+ s2 = max(m)
+ for i, c in enumerate(s1):
+ if c != s2[i]:
+ return s1[:i]
+ return s1
+
+# Are two stat buffers (obtained from stat, fstat or lstat)
+# describing the same file?
+def samestat(s1, s2):
+ """Test whether two stat buffers reference the same file"""
+ return (s1.st_ino == s2.st_ino and
+ s1.st_dev == s2.st_dev)
+
+
+# Are two filenames really pointing to the same file?
+def samefile(f1, f2):
+ """Test whether two pathnames reference the same actual file"""
+ s1 = os.stat(f1)
+ s2 = os.stat(f2)
+ return samestat(s1, s2)
+
+
+# Are two open files really referencing the same file?
+# (Not necessarily the same file descriptor!)
+def sameopenfile(fp1, fp2):
+ """Test whether two open file objects reference the same file"""
+ s1 = os.fstat(fp1)
+ s2 = os.fstat(fp2)
+ return samestat(s1, s2)
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+# Generic implementation of splitext, to be parametrized with
+# the separators
+def _splitext(p, sep, altsep, extsep):
+ """Split the extension from a pathname.
+
+ Extension is everything from the last dot to the end, ignoring
+ leading dots. Returns "(root, ext)"; ext may be empty."""
+ # NOTE: This code must work for text and bytes strings.
+
+ sepIndex = p.rfind(sep)
+ if altsep:
+ altsepIndex = p.rfind(altsep)
+ sepIndex = max(sepIndex, altsepIndex)
+
+ dotIndex = p.rfind(extsep)
+ if dotIndex > sepIndex:
+ # skip all leading dots
+ filenameIndex = sepIndex + 1
+ while filenameIndex < dotIndex:
+ if p[filenameIndex:filenameIndex+1] != extsep:
+ return p[:dotIndex], p[dotIndex:]
+ filenameIndex += 1
+
+ return p, p[:0]
+
+def _check_arg_types(funcname, *args):
+ hasstr = hasbytes = False
+ for s in args:
+ if isinstance(s, str):
+ hasstr = True
+ elif isinstance(s, bytes):
+ hasbytes = True
+ else:
+ raise TypeError('%s() argument must be str or bytes, not %r' %
+ (funcname, s.__class__.__name__)) from None
+ if hasstr and hasbytes:
+ raise TypeError("Can't mix strings and bytes in path components") from None
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/glob.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/glob.py
new file mode 100644
index 00000000..d6eca248
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/glob.py
@@ -0,0 +1,110 @@
+"""Filename globbing utility."""
+
+import os
+import re
+import fnmatch
+
+__all__ = ["glob", "iglob"]
+
+def glob(pathname):
+ """Return a list of paths matching a pathname pattern.
+
+ The pattern may contain simple shell-style wildcards a la
+ fnmatch. However, unlike fnmatch, filenames starting with a
+ dot are special cases that are not matched by '*' and '?'
+ patterns.
+
+ """
+ return list(iglob(pathname))
+
+def iglob(pathname):
+ """Return an iterator which yields the paths matching a pathname pattern.
+
+ The pattern may contain simple shell-style wildcards a la
+ fnmatch. However, unlike fnmatch, filenames starting with a
+ dot are special cases that are not matched by '*' and '?'
+ patterns.
+
+ """
+ dirname, basename = os.path.split(pathname)
+ if not has_magic(pathname):
+ if basename:
+ if os.path.lexists(pathname):
+ yield pathname
+ else:
+ # Patterns ending with a slash should match only directories
+ if os.path.isdir(dirname):
+ yield pathname
+ return
+ if not dirname:
+ yield from glob1(None, basename)
+ return
+ # `os.path.split()` returns the argument itself as a dirname if it is a
+ # drive or UNC path. Prevent an infinite recursion if a drive or UNC path
+ # contains magic characters (i.e. r'\\?\C:').
+ if dirname != pathname and has_magic(dirname):
+ dirs = iglob(dirname)
+ else:
+ dirs = [dirname]
+ if has_magic(basename):
+ glob_in_dir = glob1
+ else:
+ glob_in_dir = glob0
+ for dirname in dirs:
+ for name in glob_in_dir(dirname, basename):
+ yield os.path.join(dirname, name)
+
+# These 2 helper functions non-recursively glob inside a literal directory.
+# They return a list of basenames. `glob1` accepts a pattern while `glob0`
+# takes a literal basename (so it only has to check for its existence).
+
+def glob1(dirname, pattern):
+ if not dirname:
+ if isinstance(pattern, bytes):
+ dirname = bytes(os.curdir, 'ASCII')
+ else:
+ dirname = os.curdir
+ try:
+ names = os.listdir(dirname)
+ except OSError:
+ return []
+ if not _ishidden(pattern):
+ names = [x for x in names if not _ishidden(x)]
+ return fnmatch.filter(names, pattern)
+
+def glob0(dirname, basename):
+ if not basename:
+ # `os.path.split()` returns an empty basename for paths ending with a
+ # directory separator. 'q*x/' should match only directories.
+ if os.path.isdir(dirname):
+ return [basename]
+ else:
+ if os.path.lexists(os.path.join(dirname, basename)):
+ return [basename]
+ return []
+
+
+magic_check = re.compile('([*?[])')
+magic_check_bytes = re.compile(b'([*?[])')
+
+def has_magic(s):
+ if isinstance(s, bytes):
+ match = magic_check_bytes.search(s)
+ else:
+ match = magic_check.search(s)
+ return match is not None
+
+def _ishidden(path):
+ return path[0] in ('.', b'.'[0])
+
+def escape(pathname):
+ """Escape all special characters.
+ """
+ # Escaping is done by wrapping any of "*?[" between square brackets.
+ # Metacharacters do not work in the drive part and shouldn't be escaped.
+ drive, pathname = os.path.splitdrive(pathname)
+ if isinstance(pathname, bytes):
+ pathname = magic_check_bytes.sub(br'[\1]', pathname)
+ else:
+ pathname = magic_check.sub(r'[\1]', pathname)
+ return drive + pathname
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/http/client.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/http/client.py
new file mode 100644
index 00000000..fe7cb47c
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/http/client.py
@@ -0,0 +1,1481 @@
+r"""HTTP/1.1 client library
+
+<intro stuff goes here>
+<other stuff, too>
+
+HTTPConnection goes through a number of "states", which define when a client
+may legally make another request or fetch the response for a particular
+request. This diagram details these state transitions:
+
+ (null)
+ |
+ | HTTPConnection()
+ v
+ Idle
+ |
+ | putrequest()
+ v
+ Request-started
+ |
+ | ( putheader() )* endheaders()
+ v
+ Request-sent
+ |\_____________________________
+ | | getresponse() raises
+ | response = getresponse() | ConnectionError
+ v v
+ Unread-response Idle
+ [Response-headers-read]
+ |\____________________
+ | |
+ | response.read() | putrequest()
+ v v
+ Idle Req-started-unread-response
+ ______/|
+ / |
+ response.read() | | ( putheader() )* endheaders()
+ v v
+ Request-started Req-sent-unread-response
+ |
+ | response.read()
+ v
+ Request-sent
+
+This diagram presents the following rules:
+ -- a second request may not be started until {response-headers-read}
+ -- a response [object] cannot be retrieved until {request-sent}
+ -- there is no differentiation between an unread response body and a
+ partially read response body
+
+Note: this enforcement is applied by the HTTPConnection class. The
+ HTTPResponse class does not enforce this state machine, which
+ implies sophisticated clients may accelerate the request/response
+ pipeline. Caution should be taken, though: accelerating the states
+ beyond the above pattern may imply knowledge of the server's
+ connection-close behavior for certain requests. For example, it
+ is impossible to tell whether the server will close the connection
+ UNTIL the response headers have been read; this means that further
+ requests cannot be placed into the pipeline until it is known that
+ the server will NOT be closing the connection.
+
+Logical State __state __response
+------------- ------- ----------
+Idle _CS_IDLE None
+Request-started _CS_REQ_STARTED None
+Request-sent _CS_REQ_SENT None
+Unread-response _CS_IDLE <response_class>
+Req-started-unread-response _CS_REQ_STARTED <response_class>
+Req-sent-unread-response _CS_REQ_SENT <response_class>
+"""
+
+import email.parser
+import email.message
+import http
+import io
+import os
+import re
+import socket
+import collections
+from urllib.parse import urlsplit
+
+# HTTPMessage, parse_headers(), and the HTTP status code constants are
+# intentionally omitted for simplicity
+__all__ = ["HTTPResponse", "HTTPConnection",
+ "HTTPException", "NotConnected", "UnknownProtocol",
+ "UnknownTransferEncoding", "UnimplementedFileMode",
+ "IncompleteRead", "InvalidURL", "ImproperConnectionState",
+ "CannotSendRequest", "CannotSendHeader", "ResponseNotReady",
+ "BadStatusLine", "LineTooLong", "RemoteDisconnected", "error",
+ "responses"]
+
+HTTP_PORT = 80
+HTTPS_PORT = 443
+
+_UNKNOWN = 'UNKNOWN'
+
+# connection states
+_CS_IDLE = 'Idle'
+_CS_REQ_STARTED = 'Request-started'
+_CS_REQ_SENT = 'Request-sent'
+
+
+# hack to maintain backwards compatibility
+globals().update(http.HTTPStatus.__members__)
+
+# another hack to maintain backwards compatibility
+# Mapping status codes to official W3C names
+responses = {v: v.phrase for v in http.HTTPStatus.__members__.values()}
+
+# maximal amount of data to read at one time in _safe_read
+MAXAMOUNT = 1048576
+
+# maximal line length when calling readline().
+_MAXLINE = 65536
+_MAXHEADERS = 100
+
+# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
+#
+# VCHAR = %x21-7E
+# obs-text = %x80-FF
+# header-field = field-name ":" OWS field-value OWS
+# field-name = token
+# field-value = *( field-content / obs-fold )
+# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
+# field-vchar = VCHAR / obs-text
+#
+# obs-fold = CRLF 1*( SP / HTAB )
+# ; obsolete line folding
+# ; see Section 3.2.4
+
+# token = 1*tchar
+#
+# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
+# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
+# / DIGIT / ALPHA
+# ; any VCHAR, except delimiters
+#
+# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1
+
+# the patterns for both name and value are more lenient than RFC
+# definitions to allow for backwards compatibility
+_is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch
+_is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
+
+# We always set the Content-Length header for these methods because some
+# servers will otherwise respond with a 411
+_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
+
+
+def _encode(data, name='data'):
+ """Call data.encode("latin-1") but show a better error message."""
+ try:
+ return data.encode("latin-1")
+ except UnicodeEncodeError as err:
+ raise UnicodeEncodeError(
+ err.encoding,
+ err.object,
+ err.start,
+ err.end,
+ "%s (%.20r) is not valid Latin-1. Use %s.encode('utf-8') "
+ "if you want to send it encoded in UTF-8." %
+ (name.title(), data[err.start:err.end], name)) from None
+
+
+class HTTPMessage(email.message.Message):
+ # XXX The only usage of this method is in
+ # http.server.CGIHTTPRequestHandler. Maybe move the code there so
+ # that it doesn't need to be part of the public API. The API has
+ # never been defined so this could cause backwards compatibility
+ # issues.
+
+ def getallmatchingheaders(self, name):
+ """Find all header lines matching a given header name.
+
+ Look through the list of headers and find all lines matching a given
+ header name (and their continuation lines). A list of the lines is
+ returned, without interpretation. If the header does not occur, an
+ empty list is returned. If the header occurs multiple times, all
+ occurrences are returned. Case is not important in the header name.
+
+ """
+ name = name.lower() + ':'
+ n = len(name)
+ lst = []
+ hit = 0
+ for line in self.keys():
+ if line[:n].lower() == name:
+ hit = 1
+ elif not line[:1].isspace():
+ hit = 0
+ if hit:
+ lst.append(line)
+ return lst
+
+def parse_headers(fp, _class=HTTPMessage):
+ """Parses only RFC2822 headers from a file pointer.
+
+ email Parser wants to see strings rather than bytes.
+ But a TextIOWrapper around self.rfile would buffer too many bytes
+ from the stream, bytes which we later need to read as bytes.
+ So we read the correct bytes here, as bytes, for email Parser
+ to parse.
+
+ """
+ headers = []
+ while True:
+ line = fp.readline(_MAXLINE + 1)
+ if len(line) > _MAXLINE:
+ raise LineTooLong("header line")
+ headers.append(line)
+ if len(headers) > _MAXHEADERS:
+ raise HTTPException("got more than %d headers" % _MAXHEADERS)
+ if line in (b'\r\n', b'\n', b''):
+ break
+ hstring = b''.join(headers).decode('iso-8859-1')
+ return email.parser.Parser(_class=_class).parsestr(hstring)
+
+
+class HTTPResponse(io.BufferedIOBase):
+
+ # See RFC 2616 sec 19.6 and RFC 1945 sec 6 for details.
+
+ # The bytes from the socket object are iso-8859-1 strings.
+ # See RFC 2616 sec 2.2 which notes an exception for MIME-encoded
+ # text following RFC 2047. The basic status line parsing only
+ # accepts iso-8859-1.
+
+ def __init__(self, sock, debuglevel=0, method=None, url=None):
+ # If the response includes a content-length header, we need to
+ # make sure that the client doesn't read more than the
+ # specified number of bytes. If it does, it will block until
+ # the server times out and closes the connection. This will
+ # happen if a self.fp.read() is done (without a size) whether
+ # self.fp is buffered or not. So, no self.fp.read() by
+ # clients unless they know what they are doing.
+ self.fp = sock.makefile("rb")
+ self.debuglevel = debuglevel
+ self._method = method
+
+ # The HTTPResponse object is returned via urllib. The clients
+ # of http and urllib expect different attributes for the
+ # headers. headers is used here and supports urllib. msg is
+ # provided as a backwards compatibility layer for http
+ # clients.
+
+ self.headers = self.msg = None
+
+ # from the Status-Line of the response
+ self.version = _UNKNOWN # HTTP-Version
+ self.status = _UNKNOWN # Status-Code
+ self.reason = _UNKNOWN # Reason-Phrase
+
+ self.chunked = _UNKNOWN # is "chunked" being used?
+ self.chunk_left = _UNKNOWN # bytes left to read in current chunk
+ self.length = _UNKNOWN # number of bytes left in response
+ self.will_close = _UNKNOWN # conn will close at end of response
+
+ def _read_status(self):
+ line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
+ if len(line) > _MAXLINE:
+ raise LineTooLong("status line")
+ if self.debuglevel > 0:
+ print("reply:", repr(line))
+ if not line:
+ # Presumably, the server closed the connection before
+ # sending a valid response.
+ raise RemoteDisconnected("Remote end closed connection without"
+ " response")
+ try:
+ version, status, reason = line.split(None, 2)
+ except ValueError:
+ try:
+ version, status = line.split(None, 1)
+ reason = ""
+ except ValueError:
+ # empty version will cause next test to fail.
+ version = ""
+ if not version.startswith("HTTP/"):
+ self._close_conn()
+ raise BadStatusLine(line)
+
+ # The status code is a three-digit number
+ try:
+ status = int(status)
+ if status < 100 or status > 999:
+ raise BadStatusLine(line)
+ except ValueError:
+ raise BadStatusLine(line)
+ return version, status, reason
+
+ def begin(self):
+ if self.headers is not None:
+ # we've already started reading the response
+ return
+
+ # read until we get a non-100 response
+ while True:
+ version, status, reason = self._read_status()
+ if status != CONTINUE:
+ break
+ # skip the header from the 100 response
+ while True:
+ skip = self.fp.readline(_MAXLINE + 1)
+ if len(skip) > _MAXLINE:
+ raise LineTooLong("header line")
+ skip = skip.strip()
+ if not skip:
+ break
+ if self.debuglevel > 0:
+ print("header:", skip)
+
+ self.code = self.status = status
+ self.reason = reason.strip()
+ if version in ("HTTP/1.0", "HTTP/0.9"):
+ # Some servers might still return "0.9", treat it as 1.0 anyway
+ self.version = 10
+ elif version.startswith("HTTP/1."):
+ self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1
+ else:
+ raise UnknownProtocol(version)
+
+ self.headers = self.msg = parse_headers(self.fp)
+
+ if self.debuglevel > 0:
+ for hdr in self.headers:
+ print("header:", hdr + ":", self.headers.get(hdr))
+
+ # are we using the chunked-style of transfer encoding?
+ tr_enc = self.headers.get("transfer-encoding")
+ if tr_enc and tr_enc.lower() == "chunked":
+ self.chunked = True
+ self.chunk_left = None
+ else:
+ self.chunked = False
+
+ # will the connection close at the end of the response?
+ self.will_close = self._check_close()
+
+ # do we have a Content-Length?
+ # NOTE: RFC 2616, S4.4, #3 says we ignore this if tr_enc is "chunked"
+ self.length = None
+ length = self.headers.get("content-length")
+
+ # are we using the chunked-style of transfer encoding?
+ tr_enc = self.headers.get("transfer-encoding")
+ if length and not self.chunked:
+ try:
+ self.length = int(length)
+ except ValueError:
+ self.length = None
+ else:
+ if self.length < 0: # ignore nonsensical negative lengths
+ self.length = None
+ else:
+ self.length = None
+
+ # does the body have a fixed length? (of zero)
+ if (status == NO_CONTENT or status == NOT_MODIFIED or
+ 100 <= status < 200 or # 1xx codes
+ self._method == "HEAD"):
+ self.length = 0
+
+ # if the connection remains open, and we aren't using chunked, and
+ # a content-length was not provided, then assume that the connection
+ # WILL close.
+ if (not self.will_close and
+ not self.chunked and
+ self.length is None):
+ self.will_close = True
+
+ def _check_close(self):
+ conn = self.headers.get("connection")
+ if self.version == 11:
+ # An HTTP/1.1 proxy is assumed to stay open unless
+ # explicitly closed.
+ conn = self.headers.get("connection")
+ if conn and "close" in conn.lower():
+ return True
+ return False
+
+ # Some HTTP/1.0 implementations have support for persistent
+ # connections, using rules different than HTTP/1.1.
+
+ # For older HTTP, Keep-Alive indicates persistent connection.
+ if self.headers.get("keep-alive"):
+ return False
+
+ # At least Akamai returns a "Connection: Keep-Alive" header,
+ # which was supposed to be sent by the client.
+ if conn and "keep-alive" in conn.lower():
+ return False
+
+ # Proxy-Connection is a netscape hack.
+ pconn = self.headers.get("proxy-connection")
+ if pconn and "keep-alive" in pconn.lower():
+ return False
+
+ # otherwise, assume it will close
+ return True
+
+ def _close_conn(self):
+ fp = self.fp
+ self.fp = None
+ fp.close()
+
+ def close(self):
+ try:
+ super().close() # set "closed" flag
+ finally:
+ if self.fp:
+ self._close_conn()
+
+ # These implementations are for the benefit of io.BufferedReader.
+
+ # XXX This class should probably be revised to act more like
+ # the "raw stream" that BufferedReader expects.
+
+ def flush(self):
+ super().flush()
+ if self.fp:
+ self.fp.flush()
+
+ def readable(self):
+ """Always returns True"""
+ return True
+
+ # End of "raw stream" methods
+
+ def isclosed(self):
+ """True if the connection is closed."""
+ # NOTE: it is possible that we will not ever call self.close(). This
+ # case occurs when will_close is TRUE, length is None, and we
+ # read up to the last byte, but NOT past it.
+ #
+ # IMPLIES: if will_close is FALSE, then self.close() will ALWAYS be
+ # called, meaning self.isclosed() is meaningful.
+ return self.fp is None
+
+ def read(self, amt=None):
+ if self.fp is None:
+ return b""
+
+ if self._method == "HEAD":
+ self._close_conn()
+ return b""
+
+ if amt is not None:
+ # Amount is given, implement using readinto
+ b = bytearray(amt)
+ n = self.readinto(b)
+ return memoryview(b)[:n].tobytes()
+ else:
+ # Amount is not given (unbounded read) so we must check self.length
+ # and self.chunked
+
+ if self.chunked:
+ return self._readall_chunked()
+
+ if self.length is None:
+ s = self.fp.read()
+ else:
+ try:
+ s = self._safe_read(self.length)
+ except IncompleteRead:
+ self._close_conn()
+ raise
+ self.length = 0
+ self._close_conn() # we read everything
+ return s
+
+ def readinto(self, b):
+ """Read up to len(b) bytes into bytearray b and return the number
+ of bytes read.
+ """
+
+ if self.fp is None:
+ return 0
+
+ if self._method == "HEAD":
+ self._close_conn()
+ return 0
+
+ if self.chunked:
+ return self._readinto_chunked(b)
+
+ if self.length is not None:
+ if len(b) > self.length:
+ # clip the read to the "end of response"
+ b = memoryview(b)[0:self.length]
+
+ # we do not use _safe_read() here because this may be a .will_close
+ # connection, and the user is reading more bytes than will be provided
+ # (for example, reading in 1k chunks)
+ n = self.fp.readinto(b)
+ if not n and b:
+ # Ideally, we would raise IncompleteRead if the content-length
+ # wasn't satisfied, but it might break compatibility.
+ self._close_conn()
+ elif self.length is not None:
+ self.length -= n
+ if not self.length:
+ self._close_conn()
+ return n
+
+ def _read_next_chunk_size(self):
+ # Read the next chunk size from the file
+ line = self.fp.readline(_MAXLINE + 1)
+ if len(line) > _MAXLINE:
+ raise LineTooLong("chunk size")
+ i = line.find(b";")
+ if i >= 0:
+ line = line[:i] # strip chunk-extensions
+ try:
+ return int(line, 16)
+ except ValueError:
+ # close the connection as protocol synchronisation is
+ # probably lost
+ self._close_conn()
+ raise
+
+ def _read_and_discard_trailer(self):
+ # read and discard trailer up to the CRLF terminator
+ ### note: we shouldn't have any trailers!
+ while True:
+ line = self.fp.readline(_MAXLINE + 1)
+ if len(line) > _MAXLINE:
+ raise LineTooLong("trailer line")
+ if not line:
+ # a vanishingly small number of sites EOF without
+ # sending the trailer
+ break
+ if line in (b'\r\n', b'\n', b''):
+ break
+
+ def _get_chunk_left(self):
+ # return self.chunk_left, reading a new chunk if necessary.
+ # chunk_left == 0: at the end of the current chunk, need to close it
+ # chunk_left == None: No current chunk, should read next.
+ # This function returns non-zero or None if the last chunk has
+ # been read.
+ chunk_left = self.chunk_left
+ if not chunk_left: # Can be 0 or None
+ if chunk_left is not None:
+ # We are at the end of chunk, discard chunk end
+ self._safe_read(2) # toss the CRLF at the end of the chunk
+ try:
+ chunk_left = self._read_next_chunk_size()
+ except ValueError:
+ raise IncompleteRead(b'')
+ if chunk_left == 0:
+ # last chunk: 1*("0") [ chunk-extension ] CRLF
+ self._read_and_discard_trailer()
+ # we read everything; close the "file"
+ self._close_conn()
+ chunk_left = None
+ self.chunk_left = chunk_left
+ return chunk_left
+
+ def _readall_chunked(self):
+ assert self.chunked != _UNKNOWN
+ value = []
+ try:
+ while True:
+ chunk_left = self._get_chunk_left()
+ if chunk_left is None:
+ break
+ value.append(self._safe_read(chunk_left))
+ self.chunk_left = 0
+ return b''.join(value)
+ except IncompleteRead:
+ raise IncompleteRead(b''.join(value))
+
+ def _readinto_chunked(self, b):
+ assert self.chunked != _UNKNOWN
+ total_bytes = 0
+ mvb = memoryview(b)
+ try:
+ while True:
+ chunk_left = self._get_chunk_left()
+ if chunk_left is None:
+ return total_bytes
+
+ if len(mvb) <= chunk_left:
+ n = self._safe_readinto(mvb)
+ self.chunk_left = chunk_left - n
+ return total_bytes + n
+
+ temp_mvb = mvb[:chunk_left]
+ n = self._safe_readinto(temp_mvb)
+ mvb = mvb[n:]
+ total_bytes += n
+ self.chunk_left = 0
+
+ except IncompleteRead:
+ raise IncompleteRead(bytes(b[0:total_bytes]))
+
+ def _safe_read(self, amt):
+ """Read the number of bytes requested, compensating for partial reads.
+
+ Normally, we have a blocking socket, but a read() can be interrupted
+ by a signal (resulting in a partial read).
+
+ Note that we cannot distinguish between EOF and an interrupt when zero
+ bytes have been read. IncompleteRead() will be raised in this
+ situation.
+
+ This function should be used when <amt> bytes "should" be present for
+ reading. If the bytes are truly not available (due to EOF), then the
+ IncompleteRead exception can be used to detect the problem.
+ """
+ s = []
+ while amt > 0:
+ chunk = self.fp.read(min(amt, MAXAMOUNT))
+ if not chunk:
+ raise IncompleteRead(b''.join(s), amt)
+ s.append(chunk)
+ amt -= len(chunk)
+ return b"".join(s)
+
+ def _safe_readinto(self, b):
+ """Same as _safe_read, but for reading into a buffer."""
+ total_bytes = 0
+ mvb = memoryview(b)
+ while total_bytes < len(b):
+ if MAXAMOUNT < len(mvb):
+ temp_mvb = mvb[0:MAXAMOUNT]
+ n = self.fp.readinto(temp_mvb)
+ else:
+ n = self.fp.readinto(mvb)
+ if not n:
+ raise IncompleteRead(bytes(mvb[0:total_bytes]), len(b))
+ mvb = mvb[n:]
+ total_bytes += n
+ return total_bytes
+
+ def read1(self, n=-1):
+ """Read with at most one underlying system call. If at least one
+ byte is buffered, return that instead.
+ """
+ if self.fp is None or self._method == "HEAD":
+ return b""
+ if self.chunked:
+ return self._read1_chunked(n)
+ if self.length is not None and (n < 0 or n > self.length):
+ n = self.length
+ try:
+ result = self.fp.read1(n)
+ except ValueError:
+ if n >= 0:
+ raise
+ # some implementations, like BufferedReader, don't support -1
+ # Read an arbitrarily selected largeish chunk.
+ result = self.fp.read1(16*1024)
+ if not result and n:
+ self._close_conn()
+ elif self.length is not None:
+ self.length -= len(result)
+ return result
+
+ def peek(self, n=-1):
+ # Having this enables IOBase.readline() to read more than one
+ # byte at a time
+ if self.fp is None or self._method == "HEAD":
+ return b""
+ if self.chunked:
+ return self._peek_chunked(n)
+ return self.fp.peek(n)
+
+ def readline(self, limit=-1):
+ if self.fp is None or self._method == "HEAD":
+ return b""
+ if self.chunked:
+ # Fallback to IOBase readline which uses peek() and read()
+ return super().readline(limit)
+ if self.length is not None and (limit < 0 or limit > self.length):
+ limit = self.length
+ result = self.fp.readline(limit)
+ if not result and limit:
+ self._close_conn()
+ elif self.length is not None:
+ self.length -= len(result)
+ return result
+
+ def _read1_chunked(self, n):
+ # Strictly speaking, _get_chunk_left() may cause more than one read,
+ # but that is ok, since that is to satisfy the chunked protocol.
+ chunk_left = self._get_chunk_left()
+ if chunk_left is None or n == 0:
+ return b''
+ if not (0 <= n <= chunk_left):
+ n = chunk_left # if n is negative or larger than chunk_left
+ read = self.fp.read1(n)
+ self.chunk_left -= len(read)
+ if not read:
+ raise IncompleteRead(b"")
+ return read
+
+ def _peek_chunked(self, n):
+ # Strictly speaking, _get_chunk_left() may cause more than one read,
+ # but that is ok, since that is to satisfy the chunked protocol.
+ try:
+ chunk_left = self._get_chunk_left()
+ except IncompleteRead:
+ return b'' # peek doesn't worry about protocol
+ if chunk_left is None:
+ return b'' # eof
+ # peek is allowed to return more than requested. Just request the
+ # entire chunk, and truncate what we get.
+ return self.fp.peek(chunk_left)[:chunk_left]
+
+ def fileno(self):
+ return self.fp.fileno()
+
+ def getheader(self, name, default=None):
+ '''Returns the value of the header matching *name*.
+
+ If there are multiple matching headers, the values are
+ combined into a single string separated by commas and spaces.
+
+ If no matching header is found, returns *default* or None if
+ the *default* is not specified.
+
+ If the headers are unknown, raises http.client.ResponseNotReady.
+
+ '''
+ if self.headers is None:
+ raise ResponseNotReady()
+ headers = self.headers.get_all(name) or default
+ if isinstance(headers, str) or not hasattr(headers, '__iter__'):
+ return headers
+ else:
+ return ', '.join(headers)
+
+ def getheaders(self):
+ """Return list of (header, value) tuples."""
+ if self.headers is None:
+ raise ResponseNotReady()
+ return list(self.headers.items())
+
+ # We override IOBase.__iter__ so that it doesn't check for closed-ness
+
+ def __iter__(self):
+ return self
+
+ # For compatibility with old-style urllib responses.
+
+ def info(self):
+ '''Returns an instance of the class mimetools.Message containing
+ meta-information associated with the URL.
+
+ When the method is HTTP, these headers are those returned by
+ the server at the head of the retrieved HTML page (including
+ Content-Length and Content-Type).
+
+ When the method is FTP, a Content-Length header will be
+ present if (as is now usual) the server passed back a file
+ length in response to the FTP retrieval request. A
+ Content-Type header will be present if the MIME type can be
+ guessed.
+
+ When the method is local-file, returned headers will include
+ a Date representing the file's last-modified time, a
+ Content-Length giving file size, and a Content-Type
+ containing a guess at the file's type. See also the
+ description of the mimetools module.
+
+ '''
+ return self.headers
+
+ def geturl(self):
+ '''Return the real URL of the page.
+
+ In some cases, the HTTP server redirects a client to another
+ URL. The urlopen() function handles this transparently, but in
+ some cases the caller needs to know which URL the client was
+ redirected to. The geturl() method can be used to get at this
+ redirected URL.
+
+ '''
+ return self.url
+
+ def getcode(self):
+ '''Return the HTTP status code that was sent with the response,
+ or None if the URL is not an HTTP URL.
+
+ '''
+ return self.status
+
+class HTTPConnection:
+
+ _http_vsn = 11
+ _http_vsn_str = 'HTTP/1.1'
+
+ response_class = HTTPResponse
+ default_port = HTTP_PORT
+ auto_open = 1
+ debuglevel = 0
+
+ @staticmethod
+ def _is_textIO(stream):
+ """Test whether a file-like object is a text or a binary stream.
+ """
+ return isinstance(stream, io.TextIOBase)
+
+ @staticmethod
+ def _get_content_length(body, method):
+ """Get the content-length based on the body.
+
+ If the body is None, we set Content-Length: 0 for methods that expect
+ a body (RFC 7230, Section 3.3.2). We also set the Content-Length for
+ any method if the body is a str or bytes-like object and not a file.
+ """
+ if body is None:
+ # do an explicit check for not None here to distinguish
+ # between unset and set but empty
+ if method.upper() in _METHODS_EXPECTING_BODY:
+ return 0
+ else:
+ return None
+
+ if hasattr(body, 'read'):
+ # file-like object.
+ return None
+
+ try:
+ # does it implement the buffer protocol (bytes, bytearray, array)?
+ mv = memoryview(body)
+ return mv.nbytes
+ except TypeError:
+ pass
+
+ if isinstance(body, str):
+ return len(body)
+
+ return None
+
+ def __init__(self, host, port=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
+ source_address=None):
+ self.timeout = timeout
+ self.source_address = source_address
+ self.sock = None
+ self._buffer = []
+ self.__response = None
+ self.__state = _CS_IDLE
+ self._method = None
+ self._tunnel_host = None
+ self._tunnel_port = None
+ self._tunnel_headers = {}
+
+ (self.host, self.port) = self._get_hostport(host, port)
+
+ # This is stored as an instance variable to allow unit
+ # tests to replace it with a suitable mockup
+ self._create_connection = socket.create_connection
+
+ def set_tunnel(self, host, port=None, headers=None):
+ """Set up host and port for HTTP CONNECT tunnelling.
+
+ In a connection that uses HTTP CONNECT tunneling, the host passed to the
+ constructor is used as a proxy server that relays all communication to
+ the endpoint passed to `set_tunnel`. This done by sending an HTTP
+ CONNECT request to the proxy server when the connection is established.
+
+ This method must be called before the HTML connection has been
+ established.
+
+ The headers argument should be a mapping of extra HTTP headers to send
+ with the CONNECT request.
+ """
+
+ if self.sock:
+ raise RuntimeError("Can't set up tunnel for established connection")
+
+ self._tunnel_host, self._tunnel_port = self._get_hostport(host, port)
+ if headers:
+ self._tunnel_headers = headers
+ else:
+ self._tunnel_headers.clear()
+
+ def _get_hostport(self, host, port):
+ if port is None:
+ i = host.rfind(':')
+ j = host.rfind(']') # ipv6 addresses have [...]
+ if i > j:
+ try:
+ port = int(host[i+1:])
+ except ValueError:
+ if host[i+1:] == "": # http://foo.com:/ == http://foo.com/
+ port = self.default_port
+ else:
+ raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
+ host = host[:i]
+ else:
+ port = self.default_port
+ if host and host[0] == '[' and host[-1] == ']':
+ host = host[1:-1]
+
+ return (host, port)
+
+ def set_debuglevel(self, level):
+ self.debuglevel = level
+
+ def _tunnel(self):
+ connect_str = "CONNECT %s:%d HTTP/1.0\r\n" % (self._tunnel_host,
+ self._tunnel_port)
+ connect_bytes = connect_str.encode("ascii")
+ self.send(connect_bytes)
+ for header, value in self._tunnel_headers.items():
+ header_str = "%s: %s\r\n" % (header, value)
+ header_bytes = header_str.encode("latin-1")
+ self.send(header_bytes)
+ self.send(b'\r\n')
+
+ response = self.response_class(self.sock, method=self._method)
+ (version, code, message) = response._read_status()
+
+ if code != http.HTTPStatus.OK:
+ self.close()
+ raise OSError("Tunnel connection failed: %d %s" % (code,
+ message.strip()))
+ while True:
+ line = response.fp.readline(_MAXLINE + 1)
+ if len(line) > _MAXLINE:
+ raise LineTooLong("header line")
+ if not line:
+ # for sites which EOF without sending a trailer
+ break
+ if line in (b'\r\n', b'\n', b''):
+ break
+
+ if self.debuglevel > 0:
+ print('header:', line.decode())
+
+ def connect(self):
+ """Connect to the host and port specified in __init__."""
+ self.sock = self._create_connection(
+ (self.host,self.port), self.timeout, self.source_address)
+ #self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
+
+ if self._tunnel_host:
+ self._tunnel()
+
+ def close(self):
+ """Close the connection to the HTTP server."""
+ self.__state = _CS_IDLE
+ try:
+ sock = self.sock
+ if sock:
+ self.sock = None
+ sock.close() # close it manually... there may be other refs
+ finally:
+ response = self.__response
+ if response:
+ self.__response = None
+ response.close()
+
+ def send(self, data):
+ """Send `data' to the server.
+ ``data`` can be a string object, a bytes object, an array object, a
+ file-like object that supports a .read() method, or an iterable object.
+ """
+
+ if self.sock is None:
+ if self.auto_open:
+ self.connect()
+ else:
+ raise NotConnected()
+
+ if self.debuglevel > 0:
+ print("send:", repr(data))
+ blocksize = 8192
+ if hasattr(data, "read") :
+ if self.debuglevel > 0:
+ print("sendIng a read()able")
+ encode = self._is_textIO(data)
+ if encode and self.debuglevel > 0:
+ print("encoding file using iso-8859-1")
+ while 1:
+ datablock = data.read(blocksize)
+ if not datablock:
+ break
+ if encode:
+ datablock = datablock.encode("iso-8859-1")
+ self.sock.sendall(datablock)
+ return
+ try:
+ self.sock.sendall(data)
+ except TypeError:
+ if isinstance(data, collections.Iterable):
+ for d in data:
+ self.sock.sendall(d)
+ else:
+ raise TypeError("data should be a bytes-like object "
+ "or an iterable, got %r" % type(data))
+
+ def _output(self, s):
+ """Add a line of output to the current request buffer.
+
+ Assumes that the line does *not* end with \\r\\n.
+ """
+ self._buffer.append(s)
+
+ def _read_readable(self, readable):
+ blocksize = 8192
+ if self.debuglevel > 0:
+ print("sendIng a read()able")
+ encode = self._is_textIO(readable)
+ if encode and self.debuglevel > 0:
+ print("encoding file using iso-8859-1")
+ while True:
+ datablock = readable.read(blocksize)
+ if not datablock:
+ break
+ if encode:
+ datablock = datablock.encode("iso-8859-1")
+ yield datablock
+
+ def _send_output(self, message_body=None, encode_chunked=False):
+ """Send the currently buffered request and clear the buffer.
+
+ Appends an extra \\r\\n to the buffer.
+ A message_body may be specified, to be appended to the request.
+ """
+ self._buffer.extend((b"", b""))
+ msg = b"\r\n".join(self._buffer)
+ del self._buffer[:]
+ self.send(msg)
+
+ if message_body is not None:
+
+ # create a consistent interface to message_body
+ if hasattr(message_body, 'read'):
+ # Let file-like take precedence over byte-like. This
+ # is needed to allow the current position of mmap'ed
+ # files to be taken into account.
+ chunks = self._read_readable(message_body)
+ else:
+ try:
+ # this is solely to check to see if message_body
+ # implements the buffer API. it /would/ be easier
+ # to capture if PyObject_CheckBuffer was exposed
+ # to Python.
+ memoryview(message_body)
+ except TypeError:
+ try:
+ chunks = iter(message_body)
+ except TypeError:
+ raise TypeError("message_body should be a bytes-like "
+ "object or an iterable, got %r"
+ % type(message_body))
+ else:
+ # the object implements the buffer interface and
+ # can be passed directly into socket methods
+ chunks = (message_body,)
+
+ for chunk in chunks:
+ if not chunk:
+ if self.debuglevel > 0:
+ print('Zero length chunk ignored')
+ continue
+
+ if encode_chunked and self._http_vsn == 11:
+ # chunked encoding
+ chunk = f'{len(chunk):X}\r\n'.encode('ascii') + chunk \
+ + b'\r\n'
+ self.send(chunk)
+
+ if encode_chunked and self._http_vsn == 11:
+ # end chunked transfer
+ self.send(b'0\r\n\r\n')
+
+ def putrequest(self, method, url, skip_host=False,
+ skip_accept_encoding=False):
+ """Send a request to the server.
+
+ `method' specifies an HTTP request method, e.g. 'GET'.
+ `url' specifies the object being requested, e.g. '/index.html'.
+ `skip_host' if True does not add automatically a 'Host:' header
+ `skip_accept_encoding' if True does not add automatically an
+ 'Accept-Encoding:' header
+ """
+
+ # if a prior response has been completed, then forget about it.
+ if self.__response and self.__response.isclosed():
+ self.__response = None
+
+
+ # in certain cases, we cannot issue another request on this connection.
+ # this occurs when:
+ # 1) we are in the process of sending a request. (_CS_REQ_STARTED)
+ # 2) a response to a previous request has signalled that it is going
+ # to close the connection upon completion.
+ # 3) the headers for the previous response have not been read, thus
+ # we cannot determine whether point (2) is true. (_CS_REQ_SENT)
+ #
+ # if there is no prior response, then we can request at will.
+ #
+ # if point (2) is true, then we will have passed the socket to the
+ # response (effectively meaning, "there is no prior response"), and
+ # will open a new one when a new request is made.
+ #
+ # Note: if a prior response exists, then we *can* start a new request.
+ # We are not allowed to begin fetching the response to this new
+ # request, however, until that prior response is complete.
+ #
+ if self.__state == _CS_IDLE:
+ self.__state = _CS_REQ_STARTED
+ else:
+ raise CannotSendRequest(self.__state)
+
+ # Save the method we use, we need it later in the response phase
+ self._method = method
+ if not url:
+ url = '/'
+ request = '%s %s %s' % (method, url, self._http_vsn_str)
+
+ # Non-ASCII characters should have been eliminated earlier
+ self._output(request.encode('ascii'))
+
+ if self._http_vsn == 11:
+ # Issue some standard headers for better HTTP/1.1 compliance
+
+ if not skip_host:
+ # this header is issued *only* for HTTP/1.1
+ # connections. more specifically, this means it is
+ # only issued when the client uses the new
+ # HTTPConnection() class. backwards-compat clients
+ # will be using HTTP/1.0 and those clients may be
+ # issuing this header themselves. we should NOT issue
+ # it twice; some web servers (such as Apache) barf
+ # when they see two Host: headers
+
+ # If we need a non-standard port,include it in the
+ # header. If the request is going through a proxy,
+ # but the host of the actual URL, not the host of the
+ # proxy.
+
+ netloc = ''
+ if isinstance(url,str):
+ url = bytes(url,encoding='utf-8')
+ b = url.decode('utf-8')
+ if b.startswith('http'):
+ nil, netloc, nil, nil, nil = urlsplit(url)
+
+ if netloc:
+ try:
+ netloc_enc = netloc.encode("ascii")
+ except UnicodeEncodeError:
+ netloc_enc = netloc.encode("idna")
+ self.putheader('Host', netloc_enc)
+ else:
+ if self._tunnel_host:
+ host = self._tunnel_host
+ port = self._tunnel_port
+ else:
+ host = self.host
+ port = self.port
+
+ try:
+ host_enc = host.encode("ascii")
+ except UnicodeEncodeError:
+ host_enc = host.encode("idna")
+
+ # As per RFC 273, IPv6 address should be wrapped with []
+ # when used as Host header
+
+ if host.find(':') >= 0:
+ host_enc = b'[' + host_enc + b']'
+
+ if port == self.default_port:
+ self.putheader('Host', host_enc)
+ else:
+ host_enc = host_enc.decode("ascii")
+ self.putheader('Host', "%s:%s" % (host_enc, port))
+
+ # note: we are assuming that clients will not attempt to set these
+ # headers since *this* library must deal with the
+ # consequences. this also means that when the supporting
+ # libraries are updated to recognize other forms, then this
+ # code should be changed (removed or updated).
+
+ # we only want a Content-Encoding of "identity" since we don't
+ # support encodings such as x-gzip or x-deflate.
+ if not skip_accept_encoding:
+ self.putheader('Accept-Encoding', 'identity')
+
+ # we can accept "chunked" Transfer-Encodings, but no others
+ # NOTE: no TE header implies *only* "chunked"
+ #self.putheader('TE', 'chunked')
+
+ # if TE is supplied in the header, then it must appear in a
+ # Connection header.
+ #self.putheader('Connection', 'TE')
+
+ else:
+ # For HTTP/1.0, the server will assume "not chunked"
+ pass
+
+ def putheader(self, header, *values):
+ """Send a request header line to the server.
+
+ For example: h.putheader('Accept', 'text/html')
+ """
+ if self.__state != _CS_REQ_STARTED:
+ raise CannotSendHeader()
+
+ if hasattr(header, 'encode'):
+ header = header.encode('ascii')
+
+ if not _is_legal_header_name(header):
+ raise ValueError('Invalid header name %r' % (header,))
+
+ values = list(values)
+ for i, one_value in enumerate(values):
+ if hasattr(one_value, 'encode'):
+ values[i] = one_value.encode('latin-1')
+ elif isinstance(one_value, int):
+ values[i] = str(one_value).encode('ascii')
+
+ if _is_illegal_header_value(values[i]):
+ raise ValueError('Invalid header value %r' % (values[i],))
+
+ value = b'\r\n\t'.join(values)
+ header = header + b': ' + value
+ self._output(header)
+
+ def endheaders(self, message_body=None, *, encode_chunked=False):
+ """Indicate that the last header line has been sent to the server.
+
+ This method sends the request to the server. The optional message_body
+ argument can be used to pass a message body associated with the
+ request.
+ """
+ if self.__state == _CS_REQ_STARTED:
+ self.__state = _CS_REQ_SENT
+ else:
+ raise CannotSendHeader()
+ self._send_output(message_body, encode_chunked=encode_chunked)
+
+ def request(self, method, url, body=None, headers={}, *,
+ encode_chunked=False):
+ """Send a complete request to the server."""
+ self._send_request(method, url, body, headers, encode_chunked)
+
+ def _send_request(self, method, url, body, headers, encode_chunked):
+ # Honor explicitly requested Host: and Accept-Encoding: headers.
+ header_names = frozenset(k.lower() for k in headers)
+ skips = {}
+ if 'host' in header_names:
+ skips['skip_host'] = 1
+ if 'accept-encoding' in header_names:
+ skips['skip_accept_encoding'] = 1
+
+ self.putrequest(method, url, **skips)
+
+ # chunked encoding will happen if HTTP/1.1 is used and either
+ # the caller passes encode_chunked=True or the following
+ # conditions hold:
+ # 1. content-length has not been explicitly set
+ # 2. the body is a file or iterable, but not a str or bytes-like
+ # 3. Transfer-Encoding has NOT been explicitly set by the caller
+
+ if 'content-length' not in header_names:
+ # only chunk body if not explicitly set for backwards
+ # compatibility, assuming the client code is already handling the
+ # chunking
+ if 'transfer-encoding' not in header_names:
+ # if content-length cannot be automatically determined, fall
+ # back to chunked encoding
+ encode_chunked = False
+ content_length = self._get_content_length(body, method)
+ if content_length is None:
+ if body is not None:
+ if self.debuglevel > 0:
+ print('Unable to determine size of %r' % body)
+ encode_chunked = True
+ self.putheader('Transfer-Encoding', 'chunked')
+ else:
+ self.putheader('Content-Length', str(content_length))
+ else:
+ encode_chunked = False
+
+ for hdr, value in headers.items():
+ self.putheader(hdr, value)
+ if isinstance(body, str):
+ # RFC 2616 Section 3.7.1 says that text default has a
+ # default charset of iso-8859-1.
+ body = _encode(body, 'body')
+ self.endheaders(body, encode_chunked=encode_chunked)
+
+ def getresponse(self):
+ """Get the response from the server.
+
+ If the HTTPConnection is in the correct state, returns an
+ instance of HTTPResponse or of whatever object is returned by
+ the response_class variable.
+
+ If a request has not been sent or if a previous response has
+ not be handled, ResponseNotReady is raised. If the HTTP
+ response indicates that the connection should be closed, then
+ it will be closed before the response is returned. When the
+ connection is closed, the underlying socket is closed.
+ """
+
+ # if a prior response has been completed, then forget about it.
+ if self.__response and self.__response.isclosed():
+ self.__response = None
+
+ # if a prior response exists, then it must be completed (otherwise, we
+ # cannot read this response's header to determine the connection-close
+ # behavior)
+ #
+ # note: if a prior response existed, but was connection-close, then the
+ # socket and response were made independent of this HTTPConnection
+ # object since a new request requires that we open a whole new
+ # connection
+ #
+ # this means the prior response had one of two states:
+ # 1) will_close: this connection was reset and the prior socket and
+ # response operate independently
+ # 2) persistent: the response was retained and we await its
+ # isclosed() status to become true.
+ #
+ if self.__state != _CS_REQ_SENT or self.__response:
+ raise ResponseNotReady(self.__state)
+
+ if self.debuglevel > 0:
+ response = self.response_class(self.sock, self.debuglevel,
+ method=self._method)
+ else:
+ response = self.response_class(self.sock, method=self._method)
+
+ try:
+ try:
+ response.begin()
+ except ConnectionError:
+ self.close()
+ raise
+ assert response.will_close != _UNKNOWN
+ self.__state = _CS_IDLE
+
+ if response.will_close:
+ # this effectively passes the connection to the response
+ self.close()
+ else:
+ # remember this, so we can tell when it is complete
+ self.__response = response
+
+ return response
+ except:
+ response.close()
+ raise
+
+try:
+ import ssl
+except ImportError:
+ pass
+else:
+ class HTTPSConnection(HTTPConnection):
+ "This class allows communication via SSL."
+
+ default_port = HTTPS_PORT
+
+ # XXX Should key_file and cert_file be deprecated in favour of context?
+
+ def __init__(self, host, port=None, key_file=None, cert_file=None,
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
+ source_address=None, *, context=None,
+ check_hostname=None):
+ super(HTTPSConnection, self).__init__(host, port, timeout,
+ source_address)
+ if (key_file is not None or cert_file is not None or
+ check_hostname is not None):
+ import warnings
+ warnings.warn("key_file, cert_file and check_hostname are "
+ "deprecated, use a custom context instead.",
+ DeprecationWarning, 2)
+ self.key_file = key_file
+ self.cert_file = cert_file
+ if context is None:
+ context = ssl._create_default_https_context()
+ will_verify = context.verify_mode != ssl.CERT_NONE
+ if check_hostname is None:
+ check_hostname = context.check_hostname
+ if check_hostname and not will_verify:
+ raise ValueError("check_hostname needs a SSL context with "
+ "either CERT_OPTIONAL or CERT_REQUIRED")
+ if key_file or cert_file:
+ context.load_cert_chain(cert_file, key_file)
+ self._context = context
+ self._check_hostname = check_hostname
+
+ def connect(self):
+ "Connect to a host on a given (SSL) port."
+
+ super().connect()
+
+ if self._tunnel_host:
+ server_hostname = self._tunnel_host
+ else:
+ server_hostname = self.host
+
+ self.sock = self._context.wrap_socket(self.sock,
+ server_hostname=server_hostname)
+ if not self._context.check_hostname and self._check_hostname:
+ try:
+ ssl.match_hostname(self.sock.getpeercert(), server_hostname)
+ except Exception:
+ self.sock.shutdown(socket.SHUT_RDWR)
+ self.sock.close()
+ raise
+
+ __all__.append("HTTPSConnection")
+
+class HTTPException(Exception):
+ # Subclasses that define an __init__ must call Exception.__init__
+ # or define self.args. Otherwise, str() will fail.
+ pass
+
+class NotConnected(HTTPException):
+ pass
+
+class InvalidURL(HTTPException):
+ pass
+
+class UnknownProtocol(HTTPException):
+ def __init__(self, version):
+ self.args = version,
+ self.version = version
+
+class UnknownTransferEncoding(HTTPException):
+ pass
+
+class UnimplementedFileMode(HTTPException):
+ pass
+
+class IncompleteRead(HTTPException):
+ def __init__(self, partial, expected=None):
+ self.args = partial,
+ self.partial = partial
+ self.expected = expected
+ def __repr__(self):
+ if self.expected is not None:
+ e = ', %i more expected' % self.expected
+ else:
+ e = ''
+ return '%s(%i bytes read%s)' % (self.__class__.__name__,
+ len(self.partial), e)
+ def __str__(self):
+ return repr(self)
+
+class ImproperConnectionState(HTTPException):
+ pass
+
+class CannotSendRequest(ImproperConnectionState):
+ pass
+
+class CannotSendHeader(ImproperConnectionState):
+ pass
+
+class ResponseNotReady(ImproperConnectionState):
+ pass
+
+class BadStatusLine(HTTPException):
+ def __init__(self, line):
+ if not line:
+ line = repr(line)
+ self.args = line,
+ self.line = line
+
+class LineTooLong(HTTPException):
+ def __init__(self, line_type):
+ HTTPException.__init__(self, "got more than %d bytes when reading %s"
+ % (_MAXLINE, line_type))
+
+class RemoteDisconnected(ConnectionResetError, BadStatusLine):
+ def __init__(self, *pos, **kw):
+ BadStatusLine.__init__(self, "")
+ ConnectionResetError.__init__(self, *pos, **kw)
+
+# for backwards compatibility
+error = HTTPException
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/importlib/_bootstrap_external.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/importlib/_bootstrap_external.py
new file mode 100644
index 00000000..dcf41018
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/importlib/_bootstrap_external.py
@@ -0,0 +1,1443 @@
+"""Core implementation of path-based import.
+
+This module is NOT meant to be directly imported! It has been designed such
+that it can be bootstrapped into Python as the implementation of import. As
+such it requires the injection of specific modules and attributes in order to
+work. One should use importlib as the public-facing version of this module.
+
+"""
+#
+# IMPORTANT: Whenever making changes to this module, be sure to run
+# a top-level make in order to get the frozen version of the module
+# updated. Not doing so will result in the Makefile to fail for
+# all others who don't have a ./python around to freeze the module
+# in the early stages of compilation.
+#
+
+# See importlib._setup() for what is injected into the global namespace.
+
+# When editing this code be aware that code executed at import time CANNOT
+# reference any injected objects! This includes not only global code but also
+# anything specified at the class level.
+
+# Bootstrap-related code ######################################################
+_CASE_INSENSITIVE_PLATFORMS_STR_KEY = 'win',
+_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY = 'cygwin', 'darwin'
+_CASE_INSENSITIVE_PLATFORMS = (_CASE_INSENSITIVE_PLATFORMS_BYTES_KEY
+ + _CASE_INSENSITIVE_PLATFORMS_STR_KEY)
+
+
+def _make_relax_case():
+ if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
+ if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS_STR_KEY):
+ key = 'PYTHONCASEOK'
+ else:
+ key = b'PYTHONCASEOK'
+
+ def _relax_case():
+ """True if filenames must be checked case-insensitively."""
+ return key in _os.environ
+ else:
+ def _relax_case():
+ """True if filenames must be checked case-insensitively."""
+ return False
+ return _relax_case
+
+
+def _w_long(x):
+ """Convert a 32-bit integer to little-endian."""
+ return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little')
+
+
+def _r_long(int_bytes):
+ """Convert 4 bytes in little-endian to an integer."""
+ return int.from_bytes(int_bytes, 'little')
+
+
+def _path_join(*path_parts):
+ """Replacement for os.path.join()."""
+ return path_sep.join([part.rstrip(path_separators)
+ for part in path_parts if part])
+
+
+def _path_split(path):
+ """Replacement for os.path.split()."""
+ if len(path_separators) == 1:
+ front, _, tail = path.rpartition(path_sep)
+ return front, tail
+ for x in reversed(path):
+ if x in path_separators:
+ front, tail = path.rsplit(x, maxsplit=1)
+ return front, tail
+ return '', path
+
+
+def _path_stat(path):
+ """Stat the path.
+
+ Made a separate function to make it easier to override in experiments
+ (e.g. cache stat results).
+
+ """
+ return _os.stat(path)
+
+
+def _path_is_mode_type(path, mode):
+ """Test whether the path is the specified mode type."""
+ try:
+ stat_info = _path_stat(path)
+ except OSError:
+ return False
+ return (stat_info.st_mode & 0o170000) == mode
+
+
+def _path_isfile(path):
+ """Replacement for os.path.isfile."""
+ return _path_is_mode_type(path, 0o100000)
+
+
+def _path_isdir(path):
+ """Replacement for os.path.isdir."""
+ if not path:
+ path = _os.getcwd()
+ return _path_is_mode_type(path, 0o040000)
+
+
+def _write_atomic(path, data, mode=0o666):
+ """Best-effort function to write data to a path atomically.
+ Be prepared to handle a FileExistsError if concurrent writing of the
+ temporary file is attempted."""
+ # id() is used to generate a pseudo-random filename.
+ path_tmp = '{}.{}'.format(path, id(path))
+ fd = _os.open(path_tmp,
+ _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666)
+ try:
+ # We first write data to a temporary file, and then use os.replace() to
+ # perform an atomic rename.
+ with _io.FileIO(fd, 'wb') as file:
+ file.write(data)
+ _os.rename(path_tmp, path)
+ except OSError:
+ try:
+ _os.unlink(path_tmp)
+ except OSError:
+ pass
+ raise
+
+
+_code_type = type(_write_atomic.__code__)
+
+
+# Finder/loader utility code ###############################################
+
+# Magic word to reject .pyc files generated by other Python versions.
+# It should change for each incompatible change to the bytecode.
+#
+# The value of CR and LF is incorporated so if you ever read or write
+# a .pyc file in text mode the magic number will be wrong; also, the
+# Apple MPW compiler swaps their values, botching string constants.
+#
+# There were a variety of old schemes for setting the magic number.
+# The current working scheme is to increment the previous value by
+# 10.
+#
+# Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic
+# number also includes a new "magic tag", i.e. a human readable string used
+# to represent the magic number in __pycache__ directories. When you change
+# the magic number, you must also set a new unique magic tag. Generally this
+# can be named after the Python major version of the magic number bump, but
+# it can really be anything, as long as it's different than anything else
+# that's come before. The tags are included in the following table, starting
+# with Python 3.2a0.
+#
+# Known values:
+# Python 1.5: 20121
+# Python 1.5.1: 20121
+# Python 1.5.2: 20121
+# Python 1.6: 50428
+# Python 2.0: 50823
+# Python 2.0.1: 50823
+# Python 2.1: 60202
+# Python 2.1.1: 60202
+# Python 2.1.2: 60202
+# Python 2.2: 60717
+# Python 2.3a0: 62011
+# Python 2.3a0: 62021
+# Python 2.3a0: 62011 (!)
+# Python 2.4a0: 62041
+# Python 2.4a3: 62051
+# Python 2.4b1: 62061
+# Python 2.5a0: 62071
+# Python 2.5a0: 62081 (ast-branch)
+# Python 2.5a0: 62091 (with)
+# Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
+# Python 2.5b3: 62101 (fix wrong code: for x, in ...)
+# Python 2.5b3: 62111 (fix wrong code: x += yield)
+# Python 2.5c1: 62121 (fix wrong lnotab with for loops and
+# storing constants that should have been removed)
+# Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
+# Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
+# Python 2.6a1: 62161 (WITH_CLEANUP optimization)
+# Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND)
+# Python 2.7a0: 62181 (optimize conditional branches:
+# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
+# Python 2.7a0 62191 (introduce SETUP_WITH)
+# Python 2.7a0 62201 (introduce BUILD_SET)
+# Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD)
+# Python 3000: 3000
+# 3010 (removed UNARY_CONVERT)
+# 3020 (added BUILD_SET)
+# 3030 (added keyword-only parameters)
+# 3040 (added signature annotations)
+# 3050 (print becomes a function)
+# 3060 (PEP 3115 metaclass syntax)
+# 3061 (string literals become unicode)
+# 3071 (PEP 3109 raise changes)
+# 3081 (PEP 3137 make __file__ and __name__ unicode)
+# 3091 (kill str8 interning)
+# 3101 (merge from 2.6a0, see 62151)
+# 3103 (__file__ points to source file)
+# Python 3.0a4: 3111 (WITH_CLEANUP optimization).
+# Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT)
+# Python 3.1a0: 3141 (optimize list, set and dict comprehensions:
+# change LIST_APPEND and SET_ADD, add MAP_ADD)
+# Python 3.1a0: 3151 (optimize conditional branches:
+# introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
+# Python 3.2a0: 3160 (add SETUP_WITH)
+# tag: cpython-32
+# Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
+# tag: cpython-32
+# Python 3.2a2 3180 (add DELETE_DEREF)
+# Python 3.3a0 3190 __class__ super closure changed
+# Python 3.3a0 3200 (__qualname__ added)
+# 3210 (added size modulo 2**32 to the pyc header)
+# Python 3.3a1 3220 (changed PEP 380 implementation)
+# Python 3.3a4 3230 (revert changes to implicit __class__ closure)
+# Python 3.4a1 3250 (evaluate positional default arguments before
+# keyword-only defaults)
+# Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override
+# free vars)
+# Python 3.4a1 3270 (various tweaks to the __class__ closure)
+# Python 3.4a1 3280 (remove implicit class argument)
+# Python 3.4a4 3290 (changes to __qualname__ computation)
+# Python 3.4a4 3300 (more changes to __qualname__ computation)
+# Python 3.4rc2 3310 (alter __qualname__ computation)
+# Python 3.5a0 3320 (matrix multiplication operator)
+# Python 3.5b1 3330 (PEP 448: Additional Unpacking Generalizations)
+# Python 3.5b2 3340 (fix dictionary display evaluation order #11205)
+# Python 3.5b2 3350 (add GET_YIELD_FROM_ITER opcode #24400)
+# Python 3.5.2 3351 (fix BUILD_MAP_UNPACK_WITH_CALL opcode #27286)
+# Python 3.6a0 3360 (add FORMAT_VALUE opcode #25483
+# Python 3.6a0 3361 (lineno delta of code.co_lnotab becomes signed)
+# Python 3.6a1 3370 (16 bit wordcode)
+# Python 3.6a1 3371 (add BUILD_CONST_KEY_MAP opcode #27140)
+# Python 3.6a1 3372 (MAKE_FUNCTION simplification, remove MAKE_CLOSURE
+# #27095)
+# Python 3.6b1 3373 (add BUILD_STRING opcode #27078)
+# Python 3.6b1 3375 (add SETUP_ANNOTATIONS and STORE_ANNOTATION opcodes
+# #27985)
+# Python 3.6b1 3376 (simplify CALL_FUNCTIONs & BUILD_MAP_UNPACK_WITH_CALL)
+# Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722)
+# Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257)
+# Python 3.6rc1 3379 (more thorough __class__ validation #23722)
+#
+# MAGIC must change whenever the bytecode emitted by the compiler may no
+# longer be understood by older implementations of the eval loop (usually
+# due to the addition of new opcodes).
+#
+# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
+# in PC/launcher.c must also be updated.
+
+MAGIC_NUMBER = (3379).to_bytes(2, 'little') + b'\r\n'
+_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
+
+_PYCACHE = '__pycache__'
+_OPT = 'opt-'
+
+SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed.
+
+BYTECODE_SUFFIXES = ['.pyc']
+# Deprecated.
+DEBUG_BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES = BYTECODE_SUFFIXES
+
+def cache_from_source(path, debug_override=None, *, optimization=None):
+ """Given the path to a .py file, return the path to its .pyc file.
+
+ The .py file does not need to exist; this simply returns the path to the
+ .pyc file calculated as if the .py file were imported.
+
+ The 'optimization' parameter controls the presumed optimization level of
+ the bytecode file. If 'optimization' is not None, the string representation
+ of the argument is taken and verified to be alphanumeric (else ValueError
+ is raised).
+
+ The debug_override parameter is deprecated. If debug_override is not None,
+ a True value is the same as setting 'optimization' to the empty string
+ while a False value is equivalent to setting 'optimization' to '1'.
+
+ If sys.implementation.cache_tag is None then NotImplementedError is raised.
+
+ """
+ if debug_override is not None:
+ _warnings.warn('the debug_override parameter is deprecated; use '
+ "'optimization' instead", DeprecationWarning)
+ if optimization is not None:
+ message = 'debug_override or optimization must be set to None'
+ raise TypeError(message)
+ optimization = '' if debug_override else 1
+ #path = _os.fspath(path) #JP hack
+ head, tail = _path_split(path)
+ base, sep, rest = tail.rpartition('.')
+ tag = sys.implementation.cache_tag
+ if tag is None:
+ raise NotImplementedError('sys.implementation.cache_tag is None')
+ almost_filename = ''.join([(base if base else rest), sep, tag])
+ if optimization is None:
+ if sys.flags.optimize == 0:
+ optimization = ''
+ else:
+ optimization = sys.flags.optimize
+ optimization = str(optimization)
+ if optimization != '':
+ if not optimization.isalnum():
+ raise ValueError('{!r} is not alphanumeric'.format(optimization))
+ almost_filename = '{}.{}{}'.format(almost_filename, _OPT, optimization)
+ return _path_join(head, _PYCACHE, almost_filename + BYTECODE_SUFFIXES[0])
+
+
+def source_from_cache(path):
+ """Given the path to a .pyc. file, return the path to its .py file.
+
+ The .pyc file does not need to exist; this simply returns the path to
+ the .py file calculated to correspond to the .pyc file. If path does
+ not conform to PEP 3147/488 format, ValueError will be raised. If
+ sys.implementation.cache_tag is None then NotImplementedError is raised.
+
+ """
+ if sys.implementation.cache_tag is None:
+ raise NotImplementedError('sys.implementation.cache_tag is None')
+ #path = _os.fspath(path) #JP hack
+ head, pycache_filename = _path_split(path)
+ head, pycache = _path_split(head)
+ if pycache != _PYCACHE:
+ raise ValueError('{} not bottom-level directory in '
+ '{!r}'.format(_PYCACHE, path))
+ dot_count = pycache_filename.count('.')
+ if dot_count not in {2, 3}:
+ raise ValueError('expected only 2 or 3 dots in '
+ '{!r}'.format(pycache_filename))
+ elif dot_count == 3:
+ optimization = pycache_filename.rsplit('.', 2)[-2]
+ if not optimization.startswith(_OPT):
+ raise ValueError("optimization portion of filename does not start "
+ "with {!r}".format(_OPT))
+ opt_level = optimization[len(_OPT):]
+ if not opt_level.isalnum():
+ raise ValueError("optimization level {!r} is not an alphanumeric "
+ "value".format(optimization))
+ base_filename = pycache_filename.partition('.')[0]
+ return _path_join(head, base_filename + SOURCE_SUFFIXES[0])
+
+
+def _get_sourcefile(bytecode_path):
+ """Convert a bytecode file path to a source path (if possible).
+
+ This function exists purely for backwards-compatibility for
+ PyImport_ExecCodeModuleWithFilenames() in the C API.
+
+ """
+ if len(bytecode_path) == 0:
+ return None
+ rest, _, extension = bytecode_path.rpartition('.')
+ if not rest or extension.lower()[-3:-1] != 'py':
+ return bytecode_path
+ try:
+ source_path = source_from_cache(bytecode_path)
+ except (NotImplementedError, ValueError):
+ source_path = bytecode_path[:-1]
+ return source_path if _path_isfile(source_path) else bytecode_path
+
+
+def _get_cached(filename):
+ if filename.endswith(tuple(SOURCE_SUFFIXES)):
+ try:
+ return cache_from_source(filename)
+ except NotImplementedError:
+ pass
+ elif filename.endswith(tuple(BYTECODE_SUFFIXES)):
+ return filename
+ else:
+ return None
+
+
+def _calc_mode(path):
+ """Calculate the mode permissions for a bytecode file."""
+ try:
+ mode = _path_stat(path).st_mode
+ except OSError:
+ mode = 0o666
+ # We always ensure write access so we can update cached files
+ # later even when the source files are read-only on Windows (#6074)
+ mode |= 0o200
+ return mode
+
+
+def _check_name(method):
+ """Decorator to verify that the module being requested matches the one the
+ loader can handle.
+
+ The first argument (self) must define _name which the second argument is
+ compared against. If the comparison fails then ImportError is raised.
+
+ """
+ def _check_name_wrapper(self, name=None, *args, **kwargs):
+ if name is None:
+ name = self.name
+ elif self.name != name:
+ raise ImportError('loader for %s cannot handle %s' %
+ (self.name, name), name=name)
+ return method(self, name, *args, **kwargs)
+ try:
+ _wrap = _bootstrap._wrap
+ except NameError:
+ # XXX yuck
+ def _wrap(new, old):
+ for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
+ if hasattr(old, replace):
+ setattr(new, replace, getattr(old, replace))
+ new.__dict__.update(old.__dict__)
+ _wrap(_check_name_wrapper, method)
+ return _check_name_wrapper
+
+
+def _find_module_shim(self, fullname):
+ """Try to find a loader for the specified module by delegating to
+ self.find_loader().
+
+ This method is deprecated in favor of finder.find_spec().
+
+ """
+ # Call find_loader(). If it returns a string (indicating this
+ # is a namespace package portion), generate a warning and
+ # return None.
+ loader, portions = self.find_loader(fullname)
+ if loader is None and len(portions):
+ msg = 'Not importing directory {}: missing __init__'
+ _warnings.warn(msg.format(portions[0]), ImportWarning)
+ return loader
+
+
+def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
+ """Validate the header of the passed-in bytecode against source_stats (if
+ given) and returning the bytecode that can be compiled by compile().
+
+ All other arguments are used to enhance error reporting.
+
+ ImportError is raised when the magic number is incorrect or the bytecode is
+ found to be stale. EOFError is raised when the data is found to be
+ truncated.
+
+ """
+ exc_details = {}
+ if name is not None:
+ exc_details['name'] = name
+ else:
+ # To prevent having to make all messages have a conditional name.
+ name = '<bytecode>'
+ if path is not None:
+ exc_details['path'] = path
+ magic = data[:4]
+ raw_timestamp = data[4:8]
+ raw_size = data[8:12]
+ if magic != MAGIC_NUMBER:
+ message = 'bad magic number in {!r}: {!r}'.format(name, magic)
+ _bootstrap._verbose_message('{}', message)
+ raise ImportError(message, **exc_details)
+ elif len(raw_timestamp) != 4:
+ message = 'reached EOF while reading timestamp in {!r}'.format(name)
+ _bootstrap._verbose_message('{}', message)
+ raise EOFError(message)
+ elif len(raw_size) != 4:
+ message = 'reached EOF while reading size of source in {!r}'.format(name)
+ _bootstrap._verbose_message('{}', message)
+ raise EOFError(message)
+ if source_stats is not None:
+ try:
+ source_mtime = int(source_stats['mtime'])
+ except KeyError:
+ pass
+ else:
+ if _r_long(raw_timestamp) != source_mtime:
+ message = 'bytecode is stale for {!r}'.format(name)
+ _bootstrap._verbose_message('{}', message)
+ raise ImportError(message, **exc_details)
+ try:
+ source_size = source_stats['size'] & 0xFFFFFFFF
+ except KeyError:
+ pass
+ else:
+ if _r_long(raw_size) != source_size:
+ raise ImportError('bytecode is stale for {!r}'.format(name),
+ **exc_details)
+ return data[12:]
+
+
+def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None):
+ """Compile bytecode as returned by _validate_bytecode_header()."""
+ code = marshal.loads(data)
+ if isinstance(code, _code_type):
+ _bootstrap._verbose_message('code object from {!r}', bytecode_path)
+ if source_path is not None:
+ _imp._fix_co_filename(code, source_path)
+ return code
+ else:
+ raise ImportError('Non-code object in {!r}'.format(bytecode_path),
+ name=name, path=bytecode_path)
+
+def _code_to_bytecode(code, mtime=0, source_size=0):
+ """Compile a code object into bytecode for writing out to a byte-compiled
+ file."""
+ data = bytearray(MAGIC_NUMBER)
+ data.extend(_w_long(mtime))
+ data.extend(_w_long(source_size))
+ data.extend(marshal.dumps(code))
+ return data
+
+
+def decode_source(source_bytes):
+ """Decode bytes representing source code and return the string.
+
+ Universal newline support is used in the decoding.
+ """
+ import tokenize # To avoid bootstrap issues.
+ source_bytes_readline = _io.BytesIO(source_bytes).readline
+ encoding = tokenize.detect_encoding(source_bytes_readline)
+ newline_decoder = _io.IncrementalNewlineDecoder(None, True)
+ return newline_decoder.decode(source_bytes.decode(encoding[0]))
+
+
+# Module specifications #######################################################
+
+_POPULATE = object()
+
+
+def spec_from_file_location(name, location=None, *, loader=None,
+ submodule_search_locations=_POPULATE):
+ """Return a module spec based on a file location.
+
+ To indicate that the module is a package, set
+ submodule_search_locations to a list of directory paths. An
+ empty list is sufficient, though its not otherwise useful to the
+ import system.
+
+ The loader must take a spec as its only __init__() arg.
+
+ """
+ if location is None:
+ # The caller may simply want a partially populated location-
+ # oriented spec. So we set the location to a bogus value and
+ # fill in as much as we can.
+ location = '<unknown>'
+ if hasattr(loader, 'get_filename'):
+ # ExecutionLoader
+ try:
+ location = loader.get_filename(name)
+ except ImportError:
+ pass
+ else:
+ #location = _os.fspath(location) #JP hack
+ location = location
+ # If the location is on the filesystem, but doesn't actually exist,
+ # we could return None here, indicating that the location is not
+ # valid. However, we don't have a good way of testing since an
+ # indirect location (e.g. a zip file or URL) will look like a
+ # non-existent file relative to the filesystem.
+
+ spec = _bootstrap.ModuleSpec(name, loader, origin=location)
+ spec._set_fileattr = True
+
+ # Pick a loader if one wasn't provided.
+ if loader is None:
+ for loader_class, suffixes in _get_supported_file_loaders():
+ if location.endswith(tuple(suffixes)):
+ loader = loader_class(name, location)
+ spec.loader = loader
+ break
+ else:
+ return None
+
+ # Set submodule_search_paths appropriately.
+ if submodule_search_locations is _POPULATE:
+ # Check the loader.
+ if hasattr(loader, 'is_package'):
+ try:
+ is_package = loader.is_package(name)
+ except ImportError:
+ pass
+ else:
+ if is_package:
+ spec.submodule_search_locations = []
+ else:
+ spec.submodule_search_locations = submodule_search_locations
+ if spec.submodule_search_locations == []:
+ if location:
+ dirname = _path_split(location)[0]
+ spec.submodule_search_locations.append(dirname)
+
+ return spec
+
+
+# Loaders #####################################################################
+
+class WindowsRegistryFinder:
+
+ """Meta path finder for modules declared in the Windows registry."""
+
+ REGISTRY_KEY = (
+ 'Software\\Python\\PythonCore\\{sys_version}'
+ '\\Modules\\{fullname}')
+ REGISTRY_KEY_DEBUG = (
+ 'Software\\Python\\PythonCore\\{sys_version}'
+ '\\Modules\\{fullname}\\Debug')
+ DEBUG_BUILD = False # Changed in _setup()
+
+ @classmethod
+ def _open_registry(cls, key):
+ try:
+ return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
+ except OSError:
+ return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
+
+ @classmethod
+ def _search_registry(cls, fullname):
+ if cls.DEBUG_BUILD:
+ registry_key = cls.REGISTRY_KEY_DEBUG
+ else:
+ registry_key = cls.REGISTRY_KEY
+ key = registry_key.format(fullname=fullname,
+ sys_version='%d.%d' % sys.version_info[:2])
+ try:
+ with cls._open_registry(key) as hkey:
+ filepath = _winreg.QueryValue(hkey, '')
+ except OSError:
+ return None
+ return filepath
+
+ @classmethod
+ def find_spec(cls, fullname, path=None, target=None):
+ filepath = cls._search_registry(fullname)
+ if filepath is None:
+ return None
+ try:
+ _path_stat(filepath)
+ except OSError:
+ return None
+ for loader, suffixes in _get_supported_file_loaders():
+ if filepath.endswith(tuple(suffixes)):
+ spec = _bootstrap.spec_from_loader(fullname,
+ loader(fullname, filepath),
+ origin=filepath)
+ return spec
+
+ @classmethod
+ def find_module(cls, fullname, path=None):
+ """Find module named in the registry.
+
+ This method is deprecated. Use exec_module() instead.
+
+ """
+ spec = cls.find_spec(fullname, path)
+ if spec is not None:
+ return spec.loader
+ else:
+ return None
+
+
+class _LoaderBasics:
+
+ """Base class of common code needed by both SourceLoader and
+ SourcelessFileLoader."""
+
+ def is_package(self, fullname):
+ """Concrete implementation of InspectLoader.is_package by checking if
+ the path returned by get_filename has a filename of '__init__.py'."""
+ filename = _path_split(self.get_filename(fullname))[1]
+ filename_base = filename.rsplit('.', 1)[0]
+ tail_name = fullname.rpartition('.')[2]
+ return filename_base == '__init__' and tail_name != '__init__'
+
+ def create_module(self, spec):
+ """Use default semantics for module creation."""
+
+ def exec_module(self, module):
+ """Execute the module."""
+ code = self.get_code(module.__name__)
+ if code is None:
+ raise ImportError('cannot load module {!r} when get_code() '
+ 'returns None'.format(module.__name__))
+ _bootstrap._call_with_frames_removed(exec, code, module.__dict__)
+
+ def load_module(self, fullname):
+ """This module is deprecated."""
+ return _bootstrap._load_module_shim(self, fullname)
+
+
+class SourceLoader(_LoaderBasics):
+
+ def path_mtime(self, path):
+ """Optional method that returns the modification time (an int) for the
+ specified path, where path is a str.
+
+ Raises IOError when the path cannot be handled.
+ """
+ raise IOError
+
+ def path_stats(self, path):
+ """Optional method returning a metadata dict for the specified path
+ to by the path (str).
+ Possible keys:
+ - 'mtime' (mandatory) is the numeric timestamp of last source
+ code modification;
+ - 'size' (optional) is the size in bytes of the source code.
+
+ Implementing this method allows the loader to read bytecode files.
+ Raises IOError when the path cannot be handled.
+ """
+ return {'mtime': self.path_mtime(path)}
+
+ def _cache_bytecode(self, source_path, cache_path, data):
+ """Optional method which writes data (bytes) to a file path (a str).
+
+ Implementing this method allows for the writing of bytecode files.
+
+ The source path is needed in order to correctly transfer permissions
+ """
+ # For backwards compatibility, we delegate to set_data()
+ return self.set_data(cache_path, data)
+
+ def set_data(self, path, data):
+ """Optional method which writes data (bytes) to a file path (a str).
+
+ Implementing this method allows for the writing of bytecode files.
+ """
+
+
+ def get_source(self, fullname):
+ """Concrete implementation of InspectLoader.get_source."""
+ path = self.get_filename(fullname)
+ try:
+ source_bytes = self.get_data(path)
+ except OSError as exc:
+ raise ImportError('source not available through get_data()',
+ name=fullname) from exc
+ return decode_source(source_bytes)
+
+ def source_to_code(self, data, path, *, _optimize=-1):
+ """Return the code object compiled from source.
+
+ The 'data' argument can be any object type that compile() supports.
+ """
+ return _bootstrap._call_with_frames_removed(compile, data, path, 'exec',
+ dont_inherit=True, optimize=_optimize)
+
+ def get_code(self, fullname):
+ """Concrete implementation of InspectLoader.get_code.
+
+ Reading of bytecode requires path_stats to be implemented. To write
+ bytecode, set_data must also be implemented.
+
+ """
+ source_path = self.get_filename(fullname)
+ source_mtime = None
+ try:
+ bytecode_path = cache_from_source(source_path)
+ except NotImplementedError:
+ bytecode_path = None
+ else:
+ try:
+ st = self.path_stats(source_path)
+ except IOError:
+ pass
+ else:
+ source_mtime = int(st['mtime'])
+ try:
+ data = self.get_data(bytecode_path)
+ except OSError:
+ pass
+ else:
+ try:
+ bytes_data = _validate_bytecode_header(data,
+ source_stats=st, name=fullname,
+ path=bytecode_path)
+ except (ImportError, EOFError):
+ pass
+ else:
+ _bootstrap._verbose_message('{} matches {}', bytecode_path,
+ source_path)
+ return _compile_bytecode(bytes_data, name=fullname,
+ bytecode_path=bytecode_path,
+ source_path=source_path)
+ source_bytes = self.get_data(source_path)
+ code_object = self.source_to_code(source_bytes, source_path)
+ _bootstrap._verbose_message('code object from {}', source_path)
+ if (not sys.dont_write_bytecode and bytecode_path is not None and
+ source_mtime is not None):
+ data = _code_to_bytecode(code_object, source_mtime,
+ len(source_bytes))
+ try:
+ self._cache_bytecode(source_path, bytecode_path, data)
+ _bootstrap._verbose_message('wrote {!r}', bytecode_path)
+ except NotImplementedError:
+ pass
+ return code_object
+
+
+class FileLoader:
+
+ """Base file loader class which implements the loader protocol methods that
+ require file system usage."""
+
+ def __init__(self, fullname, path):
+ """Cache the module name and the path to the file found by the
+ finder."""
+ self.name = fullname
+ self.path = path
+
+ def __eq__(self, other):
+ return (self.__class__ == other.__class__ and
+ self.__dict__ == other.__dict__)
+
+ def __hash__(self):
+ return hash(self.name) ^ hash(self.path)
+
+ @_check_name
+ def load_module(self, fullname):
+ """Load a module from a file.
+
+ This method is deprecated. Use exec_module() instead.
+
+ """
+ # The only reason for this method is for the name check.
+ # Issue #14857: Avoid the zero-argument form of super so the implementation
+ # of that form can be updated without breaking the frozen module
+ return super(FileLoader, self).load_module(fullname)
+
+ @_check_name
+ def get_filename(self, fullname):
+ """Return the path to the source file as found by the finder."""
+ return self.path
+
+ def get_data(self, path):
+ """Return the data from path as raw bytes."""
+ with _io.FileIO(path, 'r') as file:
+ return file.read()
+
+
+class SourceFileLoader(FileLoader, SourceLoader):
+
+ """Concrete implementation of SourceLoader using the file system."""
+
+ def path_stats(self, path):
+ """Return the metadata for the path."""
+ st = _path_stat(path)
+ return {'mtime': st.st_mtime, 'size': st.st_size}
+
+ def _cache_bytecode(self, source_path, bytecode_path, data):
+ # Adapt between the two APIs
+ mode = _calc_mode(source_path)
+ return self.set_data(bytecode_path, data, _mode=mode)
+
+ def set_data(self, path, data, *, _mode=0o666):
+ """Write bytes data to a file."""
+ parent, filename = _path_split(path)
+ path_parts = []
+ # Figure out what directories are missing.
+ while parent and not _path_isdir(parent):
+ parent, part = _path_split(parent)
+ path_parts.append(part)
+ # Create needed directories.
+ for part in reversed(path_parts):
+ parent = _path_join(parent, part)
+ try:
+ _os.mkdir(parent)
+ except FileExistsError:
+ # Probably another Python process already created the dir.
+ continue
+ except OSError as exc:
+ # Could be a permission error, read-only filesystem: just forget
+ # about writing the data.
+ _bootstrap._verbose_message('could not create {!r}: {!r}',
+ parent, exc)
+ return
+ try:
+ _write_atomic(path, data, _mode)
+ _bootstrap._verbose_message('created {!r}', path)
+ except OSError as exc:
+ # Same as above: just don't write the bytecode.
+ _bootstrap._verbose_message('could not create {!r}: {!r}', path,
+ exc)
+
+
+class SourcelessFileLoader(FileLoader, _LoaderBasics):
+
+ """Loader which handles sourceless file imports."""
+
+ def get_code(self, fullname):
+ path = self.get_filename(fullname)
+ data = self.get_data(path)
+ bytes_data = _validate_bytecode_header(data, name=fullname, path=path)
+ return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
+
+ def get_source(self, fullname):
+ """Return None as there is no source code."""
+ return None
+
+
+# Filled in by _setup().
+EXTENSION_SUFFIXES = []
+
+
+class ExtensionFileLoader(FileLoader, _LoaderBasics):
+
+ """Loader for extension modules.
+
+ The constructor is designed to work with FileFinder.
+
+ """
+
+ def __init__(self, name, path):
+ self.name = name
+ self.path = path
+
+ def __eq__(self, other):
+ return (self.__class__ == other.__class__ and
+ self.__dict__ == other.__dict__)
+
+ def __hash__(self):
+ return hash(self.name) ^ hash(self.path)
+
+ def create_module(self, spec):
+ """Create an unitialized extension module"""
+ module = _bootstrap._call_with_frames_removed(
+ _imp.create_dynamic, spec)
+ _bootstrap._verbose_message('extension module {!r} loaded from {!r}',
+ spec.name, self.path)
+ return module
+
+ def exec_module(self, module):
+ """Initialize an extension module"""
+ _bootstrap._call_with_frames_removed(_imp.exec_dynamic, module)
+ _bootstrap._verbose_message('extension module {!r} executed from {!r}',
+ self.name, self.path)
+
+ def is_package(self, fullname):
+ """Return True if the extension module is a package."""
+ file_name = _path_split(self.path)[1]
+ return any(file_name == '__init__' + suffix
+ for suffix in EXTENSION_SUFFIXES)
+
+ def get_code(self, fullname):
+ """Return None as an extension module cannot create a code object."""
+ return None
+
+ def get_source(self, fullname):
+ """Return None as extension modules have no source code."""
+ return None
+
+ @_check_name
+ def get_filename(self, fullname):
+ """Return the path to the source file as found by the finder."""
+ return self.path
+
+
+class _NamespacePath:
+ """Represents a namespace package's path. It uses the module name
+ to find its parent module, and from there it looks up the parent's
+ __path__. When this changes, the module's own path is recomputed,
+ using path_finder. For top-level modules, the parent module's path
+ is sys.path."""
+
+ def __init__(self, name, path, path_finder):
+ self._name = name
+ self._path = path
+ self._last_parent_path = tuple(self._get_parent_path())
+ self._path_finder = path_finder
+
+ def _find_parent_path_names(self):
+ """Returns a tuple of (parent-module-name, parent-path-attr-name)"""
+ parent, dot, me = self._name.rpartition('.')
+ if dot == '':
+ # This is a top-level module. sys.path contains the parent path.
+ return 'sys', 'path'
+ # Not a top-level module. parent-module.__path__ contains the
+ # parent path.
+ return parent, '__path__'
+
+ def _get_parent_path(self):
+ parent_module_name, path_attr_name = self._find_parent_path_names()
+ return getattr(sys.modules[parent_module_name], path_attr_name)
+
+ def _recalculate(self):
+ # If the parent's path has changed, recalculate _path
+ parent_path = tuple(self._get_parent_path()) # Make a copy
+ if parent_path != self._last_parent_path:
+ spec = self._path_finder(self._name, parent_path)
+ # Note that no changes are made if a loader is returned, but we
+ # do remember the new parent path
+ if spec is not None and spec.loader is None:
+ if spec.submodule_search_locations:
+ self._path = spec.submodule_search_locations
+ self._last_parent_path = parent_path # Save the copy
+ return self._path
+
+ def __iter__(self):
+ return iter(self._recalculate())
+
+ def __setitem__(self, index, path):
+ self._path[index] = path
+
+ def __len__(self):
+ return len(self._recalculate())
+
+ def __repr__(self):
+ return '_NamespacePath({!r})'.format(self._path)
+
+ def __contains__(self, item):
+ return item in self._recalculate()
+
+ def append(self, item):
+ self._path.append(item)
+
+
+# We use this exclusively in module_from_spec() for backward-compatibility.
+class _NamespaceLoader:
+ def __init__(self, name, path, path_finder):
+ self._path = _NamespacePath(name, path, path_finder)
+
+ @classmethod
+ def module_repr(cls, module):
+ """Return repr for the module.
+
+ The method is deprecated. The import machinery does the job itself.
+
+ """
+ return '<module {!r} (namespace)>'.format(module.__name__)
+
+ def is_package(self, fullname):
+ return True
+
+ def get_source(self, fullname):
+ return ''
+
+ def get_code(self, fullname):
+ return compile('', '<string>', 'exec', dont_inherit=True)
+
+ def create_module(self, spec):
+ """Use default semantics for module creation."""
+
+ def exec_module(self, module):
+ pass
+
+ def load_module(self, fullname):
+ """Load a namespace module.
+
+ This method is deprecated. Use exec_module() instead.
+
+ """
+ # The import system never calls this method.
+ _bootstrap._verbose_message('namespace module loaded with path {!r}',
+ self._path)
+ return _bootstrap._load_module_shim(self, fullname)
+
+
+# Finders #####################################################################
+
+class PathFinder:
+
+ """Meta path finder for sys.path and package __path__ attributes."""
+
+ @classmethod
+ def invalidate_caches(cls):
+ """Call the invalidate_caches() method on all path entry finders
+ stored in sys.path_importer_caches (where implemented)."""
+ for finder in sys.path_importer_cache.values():
+ if hasattr(finder, 'invalidate_caches'):
+ finder.invalidate_caches()
+
+ @classmethod
+ def _path_hooks(cls, path):
+ """Search sys.path_hooks for a finder for 'path'."""
+ if sys.path_hooks is not None and not sys.path_hooks:
+ _warnings.warn('sys.path_hooks is empty', ImportWarning)
+ for hook in sys.path_hooks:
+ try:
+ return hook(path)
+ except ImportError:
+ continue
+ else:
+ return None
+
+ @classmethod
+ def _path_importer_cache(cls, path):
+ """Get the finder for the path entry from sys.path_importer_cache.
+
+ If the path entry is not in the cache, find the appropriate finder
+ and cache it. If no finder is available, store None.
+
+ """
+ if path == '':
+ try:
+ path = _os.getcwd()
+ except FileNotFoundError:
+ # Don't cache the failure as the cwd can easily change to
+ # a valid directory later on.
+ return None
+ try:
+ finder = sys.path_importer_cache[path]
+ except KeyError:
+ finder = cls._path_hooks(path)
+ sys.path_importer_cache[path] = finder
+ return finder
+
+ @classmethod
+ def _legacy_get_spec(cls, fullname, finder):
+ # This would be a good place for a DeprecationWarning if
+ # we ended up going that route.
+ if hasattr(finder, 'find_loader'):
+ loader, portions = finder.find_loader(fullname)
+ else:
+ loader = finder.find_module(fullname)
+ portions = []
+ if loader is not None:
+ return _bootstrap.spec_from_loader(fullname, loader)
+ spec = _bootstrap.ModuleSpec(fullname, None)
+ spec.submodule_search_locations = portions
+ return spec
+
+ @classmethod
+ def _get_spec(cls, fullname, path, target=None):
+ """Find the loader or namespace_path for this module/package name."""
+ # If this ends up being a namespace package, namespace_path is
+ # the list of paths that will become its __path__
+ namespace_path = []
+ for entry in path:
+ if not isinstance(entry, (str, bytes)):
+ continue
+ finder = cls._path_importer_cache(entry)
+ if finder is not None:
+ if hasattr(finder, 'find_spec'):
+ spec = finder.find_spec(fullname, target)
+ else:
+ spec = cls._legacy_get_spec(fullname, finder)
+ if spec is None:
+ continue
+ if spec.loader is not None:
+ return spec
+ portions = spec.submodule_search_locations
+ if portions is None:
+ raise ImportError('spec missing loader')
+ # This is possibly part of a namespace package.
+ # Remember these path entries (if any) for when we
+ # create a namespace package, and continue iterating
+ # on path.
+ namespace_path.extend(portions)
+ else:
+ spec = _bootstrap.ModuleSpec(fullname, None)
+ spec.submodule_search_locations = namespace_path
+ return spec
+
+ @classmethod
+ def find_spec(cls, fullname, path=None, target=None):
+ """Try to find a spec for 'fullname' on sys.path or 'path'.
+
+ The search is based on sys.path_hooks and sys.path_importer_cache.
+ """
+ if path is None:
+ path = sys.path
+ spec = cls._get_spec(fullname, path, target)
+ if spec is None:
+ return None
+ elif spec.loader is None:
+ namespace_path = spec.submodule_search_locations
+ if namespace_path:
+ # We found at least one namespace path. Return a
+ # spec which can create the namespace package.
+ spec.origin = 'namespace'
+ spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec)
+ return spec
+ else:
+ return None
+ else:
+ return spec
+
+ @classmethod
+ def find_module(cls, fullname, path=None):
+ """find the module on sys.path or 'path' based on sys.path_hooks and
+ sys.path_importer_cache.
+
+ This method is deprecated. Use find_spec() instead.
+
+ """
+ spec = cls.find_spec(fullname, path)
+ if spec is None:
+ return None
+ return spec.loader
+
+
+class FileFinder:
+
+ """File-based finder.
+
+ Interactions with the file system are cached for performance, being
+ refreshed when the directory the finder is handling has been modified.
+
+ """
+
+ def __init__(self, path, *loader_details):
+ """Initialize with the path to search on and a variable number of
+ 2-tuples containing the loader and the file suffixes the loader
+ recognizes."""
+ loaders = []
+ for loader, suffixes in loader_details:
+ loaders.extend((suffix, loader) for suffix in suffixes)
+ self._loaders = loaders
+ # Base (directory) path
+ self.path = path or '.'
+ self._path_mtime = -1
+ self._path_cache = set()
+ self._relaxed_path_cache = set()
+
+ def invalidate_caches(self):
+ """Invalidate the directory mtime."""
+ self._path_mtime = -1
+
+ find_module = _find_module_shim
+
+ def find_loader(self, fullname):
+ """Try to find a loader for the specified module, or the namespace
+ package portions. Returns (loader, list-of-portions).
+
+ This method is deprecated. Use find_spec() instead.
+
+ """
+ spec = self.find_spec(fullname)
+ if spec is None:
+ return None, []
+ return spec.loader, spec.submodule_search_locations or []
+
+ def _get_spec(self, loader_class, fullname, path, smsl, target):
+ loader = loader_class(fullname, path)
+ return spec_from_file_location(fullname, path, loader=loader,
+ submodule_search_locations=smsl)
+
+ def find_spec(self, fullname, target=None):
+ """Try to find a spec for the specified module.
+
+ Returns the matching spec, or None if not found.
+ """
+ is_namespace = False
+ tail_module = fullname.rpartition('.')[2]
+ try:
+ mtime = _path_stat(self.path or _os.getcwd()).st_mtime
+ except OSError:
+ mtime = -1
+ if mtime != self._path_mtime:
+ self._fill_cache()
+ self._path_mtime = mtime
+ # tail_module keeps the original casing, for __file__ and friends
+ if _relax_case():
+ cache = self._relaxed_path_cache
+ cache_module = tail_module.lower()
+ else:
+ cache = self._path_cache
+ cache_module = tail_module
+ # Check if the module is the name of a directory (and thus a package).
+ if cache_module in cache:
+ base_path = _path_join(self.path, tail_module)
+ for suffix, loader_class in self._loaders:
+ init_filename = '__init__' + suffix
+ full_path = _path_join(base_path, init_filename)
+ if _path_isfile(full_path):
+ return self._get_spec(loader_class, fullname, full_path, [base_path], target)
+ else:
+ # If a namespace package, return the path if we don't
+ # find a module in the next section.
+ is_namespace = _path_isdir(base_path)
+ # Check for a file w/ a proper suffix exists.
+ for suffix, loader_class in self._loaders:
+ full_path = _path_join(self.path, tail_module + suffix)
+ _bootstrap._verbose_message('trying {}', full_path, verbosity=2)
+ if cache_module + suffix in cache:
+ if _path_isfile(full_path):
+ return self._get_spec(loader_class, fullname, full_path,
+ None, target)
+ if is_namespace:
+ _bootstrap._verbose_message('possible namespace for {}', base_path)
+ spec = _bootstrap.ModuleSpec(fullname, None)
+ spec.submodule_search_locations = [base_path]
+ return spec
+ return None
+
+ def _fill_cache(self):
+ """Fill the cache of potential modules and packages for this directory."""
+ path = self.path
+ try:
+ contents = _os.listdir(path or _os.getcwd())
+ except (FileNotFoundError, PermissionError, NotADirectoryError):
+ # Directory has either been removed, turned into a file, or made
+ # unreadable.
+ contents = []
+ # We store two cached versions, to handle runtime changes of the
+ # PYTHONCASEOK environment variable.
+ if not sys.platform.startswith('win'):
+ self._path_cache = set(contents)
+ else:
+ # Windows users can import modules with case-insensitive file
+ # suffixes (for legacy reasons). Make the suffix lowercase here
+ # so it's done once instead of for every import. This is safe as
+ # the specified suffixes to check against are always specified in a
+ # case-sensitive manner.
+ lower_suffix_contents = set()
+ for item in contents:
+ name, dot, suffix = item.partition('.')
+ if dot:
+ new_name = '{}.{}'.format(name, suffix.lower())
+ else:
+ new_name = name
+ lower_suffix_contents.add(new_name)
+ self._path_cache = lower_suffix_contents
+ if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
+ self._relaxed_path_cache = {fn.lower() for fn in contents}
+
+ @classmethod
+ def path_hook(cls, *loader_details):
+ """A class method which returns a closure to use on sys.path_hook
+ which will return an instance using the specified loaders and the path
+ called on the closure.
+
+ If the path called on the closure is not a directory, ImportError is
+ raised.
+
+ """
+ def path_hook_for_FileFinder(path):
+ """Path hook for importlib.machinery.FileFinder."""
+ if not _path_isdir(path):
+ raise ImportError('only directories are supported', path=path)
+ return cls(path, *loader_details)
+
+ return path_hook_for_FileFinder
+
+ def __repr__(self):
+ return 'FileFinder({!r})'.format(self.path)
+
+
+# Import setup ###############################################################
+
+def _fix_up_module(ns, name, pathname, cpathname=None):
+ # This function is used by PyImport_ExecCodeModuleObject().
+ loader = ns.get('__loader__')
+ spec = ns.get('__spec__')
+ if not loader:
+ if spec:
+ loader = spec.loader
+ elif pathname == cpathname:
+ loader = SourcelessFileLoader(name, pathname)
+ else:
+ loader = SourceFileLoader(name, pathname)
+ if not spec:
+ spec = spec_from_file_location(name, pathname, loader=loader)
+ try:
+ ns['__spec__'] = spec
+ ns['__loader__'] = loader
+ ns['__file__'] = pathname
+ ns['__cached__'] = cpathname
+ except Exception:
+ # Not important enough to report.
+ pass
+
+
+def _get_supported_file_loaders():
+ """Returns a list of file-based module loaders.
+
+ Each item is a tuple (loader, suffixes).
+ """
+ extensions = ExtensionFileLoader, _imp.extension_suffixes()
+ source = SourceFileLoader, SOURCE_SUFFIXES
+ bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
+ return [extensions, source, bytecode]
+
+
+def _setup(_bootstrap_module):
+ """Setup the path-based importers for importlib by importing needed
+ built-in modules and injecting them into the global namespace.
+
+ Other components are extracted from the core bootstrap module.
+
+ """
+ global sys, _imp, _bootstrap
+ _bootstrap = _bootstrap_module
+ sys = _bootstrap.sys
+ _imp = _bootstrap._imp
+
+ # Directly load built-in modules needed during bootstrap.
+ self_module = sys.modules[__name__]
+ for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'):
+ if builtin_name not in sys.modules:
+ builtin_module = _bootstrap._builtin_from_name(builtin_name)
+ else:
+ builtin_module = sys.modules[builtin_name]
+ setattr(self_module, builtin_name, builtin_module)
+
+ # Directly load the os module (needed during bootstrap).
+ os_details = ('posix', ['/']), ('nt', ['\\', '/']), ('edk2', ['\\', '/'])
+ for builtin_os, path_separators in os_details:
+ # Assumption made in _path_join()
+ assert all(len(sep) == 1 for sep in path_separators)
+ path_sep = path_separators[0]
+ if builtin_os in sys.modules:
+ os_module = sys.modules[builtin_os]
+ break
+ else:
+ try:
+ os_module = _bootstrap._builtin_from_name(builtin_os)
+ break
+ except ImportError:
+ continue
+ else:
+ raise ImportError('importlib requires posix or nt or edk2')
+ setattr(self_module, '_os', os_module)
+ setattr(self_module, 'path_sep', path_sep)
+ setattr(self_module, 'path_separators', ''.join(path_separators))
+
+ # Directly load the _thread module (needed during bootstrap).
+ try:
+ thread_module = _bootstrap._builtin_from_name('_thread')
+ except ImportError:
+ # Python was built without threads
+ thread_module = None
+ setattr(self_module, '_thread', thread_module)
+
+ # Directly load the _weakref module (needed during bootstrap).
+ weakref_module = _bootstrap._builtin_from_name('_weakref')
+ setattr(self_module, '_weakref', weakref_module)
+
+ # Directly load the winreg module (needed during bootstrap).
+ if builtin_os == 'nt':
+ winreg_module = _bootstrap._builtin_from_name('winreg')
+ setattr(self_module, '_winreg', winreg_module)
+
+ # Constants
+ setattr(self_module, '_relax_case', _make_relax_case())
+ EXTENSION_SUFFIXES.extend(_imp.extension_suffixes())
+ if builtin_os == 'nt':
+ SOURCE_SUFFIXES.append('.pyw')
+ if '_d.pyd' in EXTENSION_SUFFIXES:
+ WindowsRegistryFinder.DEBUG_BUILD = True
+
+
+def _install(_bootstrap_module):
+ """Install the path-based import components."""
+ _setup(_bootstrap_module)
+ supported_loaders = _get_supported_file_loaders()
+ sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
+ sys.meta_path.append(PathFinder)
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/io.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/io.py
new file mode 100644
index 00000000..1c5ffcf9
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/io.py
@@ -0,0 +1,99 @@
+"""The io module provides the Python interfaces to stream handling. The
+builtin open function is defined in this module.
+
+At the top of the I/O hierarchy is the abstract base class IOBase. It
+defines the basic interface to a stream. Note, however, that there is no
+separation between reading and writing to streams; implementations are
+allowed to raise an OSError if they do not support a given operation.
+
+Extending IOBase is RawIOBase which deals simply with the reading and
+writing of raw bytes to a stream. FileIO subclasses RawIOBase to provide
+an interface to OS files.
+
+BufferedIOBase deals with buffering on a raw byte stream (RawIOBase). Its
+subclasses, BufferedWriter, BufferedReader, and BufferedRWPair buffer
+streams that are readable, writable, and both respectively.
+BufferedRandom provides a buffered interface to random access
+streams. BytesIO is a simple stream of in-memory bytes.
+
+Another IOBase subclass, TextIOBase, deals with the encoding and decoding
+of streams into text. TextIOWrapper, which extends it, is a buffered text
+interface to a buffered raw stream (`BufferedIOBase`). Finally, StringIO
+is an in-memory stream for text.
+
+Argument names are not part of the specification, and only the arguments
+of open() are intended to be used as keyword arguments.
+
+data:
+
+DEFAULT_BUFFER_SIZE
+
+ An int containing the default buffer size used by the module's buffered
+ I/O classes. open() uses the file's blksize (as obtained by os.stat) if
+ possible.
+"""
+# New I/O library conforming to PEP 3116.
+
+__author__ = ("Guido van Rossum <guido@python.org>, "
+ "Mike Verdone <mike.verdone@gmail.com>, "
+ "Mark Russell <mark.russell@zen.co.uk>, "
+ "Antoine Pitrou <solipsis@pitrou.net>, "
+ "Amaury Forgeot d'Arc <amauryfa@gmail.com>, "
+ "Benjamin Peterson <benjamin@python.org>")
+
+__all__ = ["BlockingIOError", "open", "IOBase", "RawIOBase", "FileIO",
+ "BytesIO", "StringIO", "BufferedIOBase",
+ "BufferedReader", "BufferedWriter", "BufferedRWPair",
+ "BufferedRandom", "TextIOBase", "TextIOWrapper",
+ "UnsupportedOperation", "SEEK_SET", "SEEK_CUR", "SEEK_END", "OpenWrapper"]
+
+
+import _io
+import abc
+
+from _io import (DEFAULT_BUFFER_SIZE, BlockingIOError, UnsupportedOperation,
+ open, FileIO, BytesIO, StringIO, BufferedReader,
+ BufferedWriter, BufferedRWPair, BufferedRandom,
+ IncrementalNewlineDecoder, TextIOWrapper)
+
+OpenWrapper = _io.open # for compatibility with _pyio
+
+# Pretend this exception was created here.
+UnsupportedOperation.__module__ = "io"
+
+# for seek()
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+
+# Declaring ABCs in C is tricky so we do it here.
+# Method descriptions and default implementations are inherited from the C
+# version however.
+class IOBase(_io._IOBase, metaclass=abc.ABCMeta):
+ __doc__ = _io._IOBase.__doc__
+
+class RawIOBase(_io._RawIOBase, IOBase):
+ __doc__ = _io._RawIOBase.__doc__
+
+class BufferedIOBase(_io._BufferedIOBase, IOBase):
+ __doc__ = _io._BufferedIOBase.__doc__
+
+class TextIOBase(_io._TextIOBase, IOBase):
+ __doc__ = _io._TextIOBase.__doc__
+
+RawIOBase.register(FileIO)
+
+for klass in (BytesIO, BufferedReader, BufferedWriter, BufferedRandom,
+ BufferedRWPair):
+ BufferedIOBase.register(klass)
+
+for klass in (StringIO, TextIOWrapper):
+ TextIOBase.register(klass)
+del klass
+
+try:
+ from _io import _WindowsConsoleIO
+except ImportError:
+ pass
+else:
+ RawIOBase.register(_WindowsConsoleIO)
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/logging/__init__.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/logging/__init__.py
new file mode 100644
index 00000000..c605b10c
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/logging/__init__.py
@@ -0,0 +1,2021 @@
+# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of Vinay Sajip
+# not be used in advertising or publicity pertaining to distribution
+# of the software without specific, written prior permission.
+# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
+# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Logging package for Python. Based on PEP 282 and comments thereto in
+comp.lang.python.
+
+Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved.
+
+To use, simply 'import logging' and log away!
+"""
+
+import sys, os, time, io, traceback, warnings, weakref, collections
+
+from string import Template
+
+__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
+ 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
+ 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
+ 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
+ 'captureWarnings', 'critical', 'debug', 'disable', 'error',
+ 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
+ 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown',
+ 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory',
+ 'lastResort', 'raiseExceptions']
+
+try:
+ import threading
+except ImportError: #pragma: no cover
+ threading = None
+
+__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
+__status__ = "production"
+# The following module attributes are no longer updated.
+__version__ = "0.5.1.2"
+__date__ = "07 February 2010"
+
+#---------------------------------------------------------------------------
+# Miscellaneous module data
+#---------------------------------------------------------------------------
+
+#
+#_startTime is used as the base when calculating the relative time of events
+#
+_startTime = time.time()
+
+#
+#raiseExceptions is used to see if exceptions during handling should be
+#propagated
+#
+raiseExceptions = True
+
+#
+# If you don't want threading information in the log, set this to zero
+#
+logThreads = True
+
+#
+# If you don't want multiprocessing information in the log, set this to zero
+#
+logMultiprocessing = True
+
+#
+# If you don't want process information in the log, set this to zero
+#
+logProcesses = True
+
+#---------------------------------------------------------------------------
+# Level related stuff
+#---------------------------------------------------------------------------
+#
+# Default levels and level names, these can be replaced with any positive set
+# of values having corresponding names. There is a pseudo-level, NOTSET, which
+# is only really there as a lower limit for user-defined levels. Handlers and
+# loggers are initialized with NOTSET so that they will log all messages, even
+# at user-defined levels.
+#
+
+CRITICAL = 50
+FATAL = CRITICAL
+ERROR = 40
+WARNING = 30
+WARN = WARNING
+INFO = 20
+DEBUG = 10
+NOTSET = 0
+
+_levelToName = {
+ CRITICAL: 'CRITICAL',
+ ERROR: 'ERROR',
+ WARNING: 'WARNING',
+ INFO: 'INFO',
+ DEBUG: 'DEBUG',
+ NOTSET: 'NOTSET',
+}
+_nameToLevel = {
+ 'CRITICAL': CRITICAL,
+ 'FATAL': FATAL,
+ 'ERROR': ERROR,
+ 'WARN': WARNING,
+ 'WARNING': WARNING,
+ 'INFO': INFO,
+ 'DEBUG': DEBUG,
+ 'NOTSET': NOTSET,
+}
+
+def getLevelName(level):
+ """
+ Return the textual representation of logging level 'level'.
+
+ If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
+ INFO, DEBUG) then you get the corresponding string. If you have
+ associated levels with names using addLevelName then the name you have
+ associated with 'level' is returned.
+
+ If a numeric value corresponding to one of the defined levels is passed
+ in, the corresponding string representation is returned.
+
+ Otherwise, the string "Level %s" % level is returned.
+ """
+ # See Issues #22386, #27937 and #29220 for why it's this way
+ result = _levelToName.get(level)
+ if result is not None:
+ return result
+ result = _nameToLevel.get(level)
+ if result is not None:
+ return result
+ return "Level %s" % level
+
+def addLevelName(level, levelName):
+ """
+ Associate 'levelName' with 'level'.
+
+ This is used when converting levels to text during message formatting.
+ """
+ _acquireLock()
+ try: #unlikely to cause an exception, but you never know...
+ _levelToName[level] = levelName
+ _nameToLevel[levelName] = level
+ finally:
+ _releaseLock()
+
+if hasattr(sys, '_getframe'):
+ currentframe = lambda: sys._getframe(3)
+else: #pragma: no cover
+ def currentframe():
+ """Return the frame object for the caller's stack frame."""
+ try:
+ raise Exception
+ except Exception:
+ return sys.exc_info()[2].tb_frame.f_back
+
+#
+# _srcfile is used when walking the stack to check when we've got the first
+# caller stack frame, by skipping frames whose filename is that of this
+# module's source. It therefore should contain the filename of this module's
+# source file.
+#
+# Ordinarily we would use __file__ for this, but frozen modules don't always
+# have __file__ set, for some reason (see Issue #21736). Thus, we get the
+# filename from a handy code object from a function defined in this module.
+# (There's no particular reason for picking addLevelName.)
+#
+
+_srcfile = os.path.normcase(addLevelName.__code__.co_filename)
+
+# _srcfile is only used in conjunction with sys._getframe().
+# To provide compatibility with older versions of Python, set _srcfile
+# to None if _getframe() is not available; this value will prevent
+# findCaller() from being called. You can also do this if you want to avoid
+# the overhead of fetching caller information, even when _getframe() is
+# available.
+#if not hasattr(sys, '_getframe'):
+# _srcfile = None
+
+
+def _checkLevel(level):
+ if isinstance(level, int):
+ rv = level
+ elif str(level) == level:
+ if level not in _nameToLevel:
+ raise ValueError("Unknown level: %r" % level)
+ rv = _nameToLevel[level]
+ else:
+ raise TypeError("Level not an integer or a valid string: %r" % level)
+ return rv
+
+#---------------------------------------------------------------------------
+# Thread-related stuff
+#---------------------------------------------------------------------------
+
+#
+#_lock is used to serialize access to shared data structures in this module.
+#This needs to be an RLock because fileConfig() creates and configures
+#Handlers, and so might arbitrary user threads. Since Handler code updates the
+#shared dictionary _handlers, it needs to acquire the lock. But if configuring,
+#the lock would already have been acquired - so we need an RLock.
+#The same argument applies to Loggers and Manager.loggerDict.
+#
+if threading:
+ _lock = threading.RLock()
+else: #pragma: no cover
+ _lock = None
+
+
+def _acquireLock():
+ """
+ Acquire the module-level lock for serializing access to shared data.
+
+ This should be released with _releaseLock().
+ """
+ if _lock:
+ _lock.acquire()
+
+def _releaseLock():
+ """
+ Release the module-level lock acquired by calling _acquireLock().
+ """
+ if _lock:
+ _lock.release()
+
+#---------------------------------------------------------------------------
+# The logging record
+#---------------------------------------------------------------------------
+
+class LogRecord(object):
+ """
+ A LogRecord instance represents an event being logged.
+
+ LogRecord instances are created every time something is logged. They
+ contain all the information pertinent to the event being logged. The
+ main information passed in is in msg and args, which are combined
+ using str(msg) % args to create the message field of the record. The
+ record also includes information such as when the record was created,
+ the source line where the logging call was made, and any exception
+ information to be logged.
+ """
+ def __init__(self, name, level, pathname, lineno,
+ msg, args, exc_info, func=None, sinfo=None, **kwargs):
+ """
+ Initialize a logging record with interesting information.
+ """
+ ct = time.time()
+ self.name = name
+ self.msg = msg
+ #
+ # The following statement allows passing of a dictionary as a sole
+ # argument, so that you can do something like
+ # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
+ # Suggested by Stefan Behnel.
+ # Note that without the test for args[0], we get a problem because
+ # during formatting, we test to see if the arg is present using
+ # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
+ # and if the passed arg fails 'if self.args:' then no formatting
+ # is done. For example, logger.warning('Value is %d', 0) would log
+ # 'Value is %d' instead of 'Value is 0'.
+ # For the use case of passing a dictionary, this should not be a
+ # problem.
+ # Issue #21172: a request was made to relax the isinstance check
+ # to hasattr(args[0], '__getitem__'). However, the docs on string
+ # formatting still seem to suggest a mapping object is required.
+ # Thus, while not removing the isinstance check, it does now look
+ # for collections.Mapping rather than, as before, dict.
+ if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
+ and args[0]):
+ args = args[0]
+ self.args = args
+ self.levelname = getLevelName(level)
+ self.levelno = level
+ self.pathname = pathname
+ try:
+ self.filename = os.path.basename(pathname)
+ self.module = os.path.splitext(self.filename)[0]
+ except (TypeError, ValueError, AttributeError):
+ self.filename = pathname
+ self.module = "Unknown module"
+ self.exc_info = exc_info
+ self.exc_text = None # used to cache the traceback text
+ self.stack_info = sinfo
+ self.lineno = lineno
+ self.funcName = func
+ self.created = ct
+ self.msecs = (ct - int(ct)) * 1000
+ self.relativeCreated = (self.created - _startTime) * 1000
+ if logThreads and threading:
+ self.thread = threading.get_ident()
+ self.threadName = threading.current_thread().name
+ else: # pragma: no cover
+ self.thread = None
+ self.threadName = None
+ if not logMultiprocessing: # pragma: no cover
+ self.processName = None
+ else:
+ self.processName = 'MainProcess'
+ mp = sys.modules.get('multiprocessing')
+ if mp is not None:
+ # Errors may occur if multiprocessing has not finished loading
+ # yet - e.g. if a custom import hook causes third-party code
+ # to run when multiprocessing calls import. See issue 8200
+ # for an example
+ try:
+ self.processName = mp.current_process().name
+ except Exception: #pragma: no cover
+ pass
+ if logProcesses and hasattr(os, 'getpid'):
+ self.process = os.getpid()
+ else:
+ self.process = None
+
+ def __str__(self):
+ return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
+ self.pathname, self.lineno, self.msg)
+
+ __repr__ = __str__
+
+ def getMessage(self):
+ """
+ Return the message for this LogRecord.
+
+ Return the message for this LogRecord after merging any user-supplied
+ arguments with the message.
+ """
+ msg = str(self.msg)
+ if self.args:
+ msg = msg % self.args
+ return msg
+
+#
+# Determine which class to use when instantiating log records.
+#
+_logRecordFactory = LogRecord
+
+def setLogRecordFactory(factory):
+ """
+ Set the factory to be used when instantiating a log record.
+
+ :param factory: A callable which will be called to instantiate
+ a log record.
+ """
+ global _logRecordFactory
+ _logRecordFactory = factory
+
+def getLogRecordFactory():
+ """
+ Return the factory to be used when instantiating a log record.
+ """
+
+ return _logRecordFactory
+
+def makeLogRecord(dict):
+ """
+ Make a LogRecord whose attributes are defined by the specified dictionary,
+ This function is useful for converting a logging event received over
+ a socket connection (which is sent as a dictionary) into a LogRecord
+ instance.
+ """
+ rv = _logRecordFactory(None, None, "", 0, "", (), None, None)
+ rv.__dict__.update(dict)
+ return rv
+
+#---------------------------------------------------------------------------
+# Formatter classes and functions
+#---------------------------------------------------------------------------
+
+class PercentStyle(object):
+
+ default_format = '%(message)s'
+ asctime_format = '%(asctime)s'
+ asctime_search = '%(asctime)'
+
+ def __init__(self, fmt):
+ self._fmt = fmt or self.default_format
+
+ def usesTime(self):
+ return self._fmt.find(self.asctime_search) >= 0
+
+ def format(self, record):
+ return self._fmt % record.__dict__
+
+class StrFormatStyle(PercentStyle):
+ default_format = '{message}'
+ asctime_format = '{asctime}'
+ asctime_search = '{asctime'
+
+ def format(self, record):
+ return self._fmt.format(**record.__dict__)
+
+
+class StringTemplateStyle(PercentStyle):
+ default_format = '${message}'
+ asctime_format = '${asctime}'
+ asctime_search = '${asctime}'
+
+ def __init__(self, fmt):
+ self._fmt = fmt or self.default_format
+ self._tpl = Template(self._fmt)
+
+ def usesTime(self):
+ fmt = self._fmt
+ return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0
+
+ def format(self, record):
+ return self._tpl.substitute(**record.__dict__)
+
+BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
+
+_STYLES = {
+ '%': (PercentStyle, BASIC_FORMAT),
+ '{': (StrFormatStyle, '{levelname}:{name}:{message}'),
+ '$': (StringTemplateStyle, '${levelname}:${name}:${message}'),
+}
+
+class Formatter(object):
+ """
+ Formatter instances are used to convert a LogRecord to text.
+
+ Formatters need to know how a LogRecord is constructed. They are
+ responsible for converting a LogRecord to (usually) a string which can
+ be interpreted by either a human or an external system. The base Formatter
+ allows a formatting string to be specified. If none is supplied, the
+ the style-dependent default value, "%(message)s", "{message}", or
+ "${message}", is used.
+
+ The Formatter can be initialized with a format string which makes use of
+ knowledge of the LogRecord attributes - e.g. the default value mentioned
+ above makes use of the fact that the user's message and arguments are pre-
+ formatted into a LogRecord's message attribute. Currently, the useful
+ attributes in a LogRecord are described by:
+
+ %(name)s Name of the logger (logging channel)
+ %(levelno)s Numeric logging level for the message (DEBUG, INFO,
+ WARNING, ERROR, CRITICAL)
+ %(levelname)s Text logging level for the message ("DEBUG", "INFO",
+ "WARNING", "ERROR", "CRITICAL")
+ %(pathname)s Full pathname of the source file where the logging
+ call was issued (if available)
+ %(filename)s Filename portion of pathname
+ %(module)s Module (name portion of filename)
+ %(lineno)d Source line number where the logging call was issued
+ (if available)
+ %(funcName)s Function name
+ %(created)f Time when the LogRecord was created (time.time()
+ return value)
+ %(asctime)s Textual time when the LogRecord was created
+ %(msecs)d Millisecond portion of the creation time
+ %(relativeCreated)d Time in milliseconds when the LogRecord was created,
+ relative to the time the logging module was loaded
+ (typically at application startup time)
+ %(thread)d Thread ID (if available)
+ %(threadName)s Thread name (if available)
+ %(process)d Process ID (if available)
+ %(message)s The result of record.getMessage(), computed just as
+ the record is emitted
+ """
+
+ converter = time.localtime
+
+ def __init__(self, fmt=None, datefmt=None, style='%'):
+ """
+ Initialize the formatter with specified format strings.
+
+ Initialize the formatter either with the specified format string, or a
+ default as described above. Allow for specialized date formatting with
+ the optional datefmt argument. If datefmt is omitted, you get an
+ ISO8601-like (or RFC 3339-like) format.
+
+ Use a style parameter of '%', '{' or '$' to specify that you want to
+ use one of %-formatting, :meth:`str.format` (``{}``) formatting or
+ :class:`string.Template` formatting in your format string.
+
+ .. versionchanged:: 3.2
+ Added the ``style`` parameter.
+ """
+ if style not in _STYLES:
+ raise ValueError('Style must be one of: %s' % ','.join(
+ _STYLES.keys()))
+ self._style = _STYLES[style][0](fmt)
+ self._fmt = self._style._fmt
+ self.datefmt = datefmt
+
+ default_time_format = '%Y-%m-%d %H:%M:%S'
+ default_msec_format = '%s,%03d'
+
+ def formatTime(self, record, datefmt=None):
+ """
+ Return the creation time of the specified LogRecord as formatted text.
+
+ This method should be called from format() by a formatter which
+ wants to make use of a formatted time. This method can be overridden
+ in formatters to provide for any specific requirement, but the
+ basic behaviour is as follows: if datefmt (a string) is specified,
+ it is used with time.strftime() to format the creation time of the
+ record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
+ The resulting string is returned. This function uses a user-configurable
+ function to convert the creation time to a tuple. By default,
+ time.localtime() is used; to change this for a particular formatter
+ instance, set the 'converter' attribute to a function with the same
+ signature as time.localtime() or time.gmtime(). To change it for all
+ formatters, for example if you want all logging times to be shown in GMT,
+ set the 'converter' attribute in the Formatter class.
+ """
+ ct = self.converter(record.created)
+ if datefmt:
+ s = time.strftime(datefmt, ct)
+ else:
+ t = time.strftime(self.default_time_format, ct)
+ s = self.default_msec_format % (t, record.msecs)
+ return s
+
+ def formatException(self, ei):
+ """
+ Format and return the specified exception information as a string.
+
+ This default implementation just uses
+ traceback.print_exception()
+ """
+ sio = io.StringIO()
+ tb = ei[2]
+ # See issues #9427, #1553375. Commented out for now.
+ #if getattr(self, 'fullstack', False):
+ # traceback.print_stack(tb.tb_frame.f_back, file=sio)
+ traceback.print_exception(ei[0], ei[1], tb, None, sio)
+ s = sio.getvalue()
+ sio.close()
+ if s[-1:] == "\n":
+ s = s[:-1]
+ return s
+
+ def usesTime(self):
+ """
+ Check if the format uses the creation time of the record.
+ """
+ return self._style.usesTime()
+
+ def formatMessage(self, record):
+ return self._style.format(record)
+
+ def formatStack(self, stack_info):
+ """
+ This method is provided as an extension point for specialized
+ formatting of stack information.
+
+ The input data is a string as returned from a call to
+ :func:`traceback.print_stack`, but with the last trailing newline
+ removed.
+
+ The base implementation just returns the value passed in.
+ """
+ return stack_info
+
+ def format(self, record):
+ """
+ Format the specified record as text.
+
+ The record's attribute dictionary is used as the operand to a
+ string formatting operation which yields the returned string.
+ Before formatting the dictionary, a couple of preparatory steps
+ are carried out. The message attribute of the record is computed
+ using LogRecord.getMessage(). If the formatting string uses the
+ time (as determined by a call to usesTime(), formatTime() is
+ called to format the event time. If there is exception information,
+ it is formatted using formatException() and appended to the message.
+ """
+ record.message = record.getMessage()
+ if self.usesTime():
+ record.asctime = self.formatTime(record, self.datefmt)
+ s = self.formatMessage(record)
+ if record.exc_info:
+ # Cache the traceback text to avoid converting it multiple times
+ # (it's constant anyway)
+ if not record.exc_text:
+ record.exc_text = self.formatException(record.exc_info)
+ if record.exc_text:
+ if s[-1:] != "\n":
+ s = s + "\n"
+ s = s + record.exc_text
+ if record.stack_info:
+ if s[-1:] != "\n":
+ s = s + "\n"
+ s = s + self.formatStack(record.stack_info)
+ return s
+
+#
+# The default formatter to use when no other is specified
+#
+_defaultFormatter = Formatter()
+
+class BufferingFormatter(object):
+ """
+ A formatter suitable for formatting a number of records.
+ """
+ def __init__(self, linefmt=None):
+ """
+ Optionally specify a formatter which will be used to format each
+ individual record.
+ """
+ if linefmt:
+ self.linefmt = linefmt
+ else:
+ self.linefmt = _defaultFormatter
+
+ def formatHeader(self, records):
+ """
+ Return the header string for the specified records.
+ """
+ return ""
+
+ def formatFooter(self, records):
+ """
+ Return the footer string for the specified records.
+ """
+ return ""
+
+ def format(self, records):
+ """
+ Format the specified records and return the result as a string.
+ """
+ rv = ""
+ if len(records) > 0:
+ rv = rv + self.formatHeader(records)
+ for record in records:
+ rv = rv + self.linefmt.format(record)
+ rv = rv + self.formatFooter(records)
+ return rv
+
+#---------------------------------------------------------------------------
+# Filter classes and functions
+#---------------------------------------------------------------------------
+
+class Filter(object):
+ """
+ Filter instances are used to perform arbitrary filtering of LogRecords.
+
+ Loggers and Handlers can optionally use Filter instances to filter
+ records as desired. The base filter class only allows events which are
+ below a certain point in the logger hierarchy. For example, a filter
+ initialized with "A.B" will allow events logged by loggers "A.B",
+ "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
+ initialized with the empty string, all events are passed.
+ """
+ def __init__(self, name=''):
+ """
+ Initialize a filter.
+
+ Initialize with the name of the logger which, together with its
+ children, will have its events allowed through the filter. If no
+ name is specified, allow every event.
+ """
+ self.name = name
+ self.nlen = len(name)
+
+ def filter(self, record):
+ """
+ Determine if the specified record is to be logged.
+
+ Is the specified record to be logged? Returns 0 for no, nonzero for
+ yes. If deemed appropriate, the record may be modified in-place.
+ """
+ if self.nlen == 0:
+ return True
+ elif self.name == record.name:
+ return True
+ elif record.name.find(self.name, 0, self.nlen) != 0:
+ return False
+ return (record.name[self.nlen] == ".")
+
+class Filterer(object):
+ """
+ A base class for loggers and handlers which allows them to share
+ common code.
+ """
+ def __init__(self):
+ """
+ Initialize the list of filters to be an empty list.
+ """
+ self.filters = []
+
+ def addFilter(self, filter):
+ """
+ Add the specified filter to this handler.
+ """
+ if not (filter in self.filters):
+ self.filters.append(filter)
+
+ def removeFilter(self, filter):
+ """
+ Remove the specified filter from this handler.
+ """
+ if filter in self.filters:
+ self.filters.remove(filter)
+
+ def filter(self, record):
+ """
+ Determine if a record is loggable by consulting all the filters.
+
+ The default is to allow the record to be logged; any filter can veto
+ this and the record is then dropped. Returns a zero value if a record
+ is to be dropped, else non-zero.
+
+ .. versionchanged:: 3.2
+
+ Allow filters to be just callables.
+ """
+ rv = True
+ for f in self.filters:
+ if hasattr(f, 'filter'):
+ result = f.filter(record)
+ else:
+ result = f(record) # assume callable - will raise if not
+ if not result:
+ rv = False
+ break
+ return rv
+
+#---------------------------------------------------------------------------
+# Handler classes and functions
+#---------------------------------------------------------------------------
+
+_handlers = weakref.WeakValueDictionary() #map of handler names to handlers
+_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
+
+def _removeHandlerRef(wr):
+ """
+ Remove a handler reference from the internal cleanup list.
+ """
+ # This function can be called during module teardown, when globals are
+ # set to None. It can also be called from another thread. So we need to
+ # pre-emptively grab the necessary globals and check if they're None,
+ # to prevent race conditions and failures during interpreter shutdown.
+ acquire, release, handlers = _acquireLock, _releaseLock, _handlerList
+ if acquire and release and handlers:
+ acquire()
+ try:
+ if wr in handlers:
+ handlers.remove(wr)
+ finally:
+ release()
+
+def _addHandlerRef(handler):
+ """
+ Add a handler to the internal cleanup list using a weak reference.
+ """
+ _acquireLock()
+ try:
+ _handlerList.append(weakref.ref(handler, _removeHandlerRef))
+ finally:
+ _releaseLock()
+
+class Handler(Filterer):
+ """
+ Handler instances dispatch logging events to specific destinations.
+
+ The base handler class. Acts as a placeholder which defines the Handler
+ interface. Handlers can optionally use Formatter instances to format
+ records as desired. By default, no formatter is specified; in this case,
+ the 'raw' message as determined by record.message is logged.
+ """
+ def __init__(self, level=NOTSET):
+ """
+ Initializes the instance - basically setting the formatter to None
+ and the filter list to empty.
+ """
+ Filterer.__init__(self)
+ self._name = None
+ self.level = _checkLevel(level)
+ self.formatter = None
+ # Add the handler to the global _handlerList (for cleanup on shutdown)
+ _addHandlerRef(self)
+ self.createLock()
+
+ def get_name(self):
+ return self._name
+
+ def set_name(self, name):
+ _acquireLock()
+ try:
+ if self._name in _handlers:
+ del _handlers[self._name]
+ self._name = name
+ if name:
+ _handlers[name] = self
+ finally:
+ _releaseLock()
+
+ name = property(get_name, set_name)
+
+ def createLock(self):
+ """
+ Acquire a thread lock for serializing access to the underlying I/O.
+ """
+ if threading:
+ self.lock = threading.RLock()
+ else: #pragma: no cover
+ self.lock = None
+
+ def acquire(self):
+ """
+ Acquire the I/O thread lock.
+ """
+ if self.lock:
+ self.lock.acquire()
+
+ def release(self):
+ """
+ Release the I/O thread lock.
+ """
+ if self.lock:
+ self.lock.release()
+
+ def setLevel(self, level):
+ """
+ Set the logging level of this handler. level must be an int or a str.
+ """
+ self.level = _checkLevel(level)
+
+ def format(self, record):
+ """
+ Format the specified record.
+
+ If a formatter is set, use it. Otherwise, use the default formatter
+ for the module.
+ """
+ if self.formatter:
+ fmt = self.formatter
+ else:
+ fmt = _defaultFormatter
+ return fmt.format(record)
+
+ def emit(self, record):
+ """
+ Do whatever it takes to actually log the specified logging record.
+
+ This version is intended to be implemented by subclasses and so
+ raises a NotImplementedError.
+ """
+ raise NotImplementedError('emit must be implemented '
+ 'by Handler subclasses')
+
+ def handle(self, record):
+ """
+ Conditionally emit the specified logging record.
+
+ Emission depends on filters which may have been added to the handler.
+ Wrap the actual emission of the record with acquisition/release of
+ the I/O thread lock. Returns whether the filter passed the record for
+ emission.
+ """
+ rv = self.filter(record)
+ if rv:
+ self.acquire()
+ try:
+ self.emit(record)
+ finally:
+ self.release()
+ return rv
+
+ def setFormatter(self, fmt):
+ """
+ Set the formatter for this handler.
+ """
+ self.formatter = fmt
+
+ def flush(self):
+ """
+ Ensure all logging output has been flushed.
+
+ This version does nothing and is intended to be implemented by
+ subclasses.
+ """
+ pass
+
+ def close(self):
+ """
+ Tidy up any resources used by the handler.
+
+ This version removes the handler from an internal map of handlers,
+ _handlers, which is used for handler lookup by name. Subclasses
+ should ensure that this gets called from overridden close()
+ methods.
+ """
+ #get the module data lock, as we're updating a shared structure.
+ _acquireLock()
+ try: #unlikely to raise an exception, but you never know...
+ if self._name and self._name in _handlers:
+ del _handlers[self._name]
+ finally:
+ _releaseLock()
+
+ def handleError(self, record):
+ """
+ Handle errors which occur during an emit() call.
+
+ This method should be called from handlers when an exception is
+ encountered during an emit() call. If raiseExceptions is false,
+ exceptions get silently ignored. This is what is mostly wanted
+ for a logging system - most users will not care about errors in
+ the logging system, they are more interested in application errors.
+ You could, however, replace this with a custom handler if you wish.
+ The record which was being processed is passed in to this method.
+ """
+ if raiseExceptions and sys.stderr: # see issue 13807
+ t, v, tb = sys.exc_info()
+ try:
+ sys.stderr.write('--- Logging error ---\n')
+ traceback.print_exception(t, v, tb, None, sys.stderr)
+ sys.stderr.write('Call stack:\n')
+ # Walk the stack frame up until we're out of logging,
+ # so as to print the calling context.
+ frame = tb.tb_frame
+ while (frame and os.path.dirname(frame.f_code.co_filename) ==
+ __path__[0]):
+ frame = frame.f_back
+ if frame:
+ traceback.print_stack(frame, file=sys.stderr)
+ else:
+ # couldn't find the right stack frame, for some reason
+ sys.stderr.write('Logged from file %s, line %s\n' % (
+ record.filename, record.lineno))
+ # Issue 18671: output logging message and arguments
+ try:
+ sys.stderr.write('Message: %r\n'
+ 'Arguments: %s\n' % (record.msg,
+ record.args))
+ except Exception:
+ sys.stderr.write('Unable to print the message and arguments'
+ ' - possible formatting error.\nUse the'
+ ' traceback above to help find the error.\n'
+ )
+ except OSError: #pragma: no cover
+ pass # see issue 5971
+ finally:
+ del t, v, tb
+
+ def __repr__(self):
+ level = getLevelName(self.level)
+ return '<%s (%s)>' % (self.__class__.__name__, level)
+
+class StreamHandler(Handler):
+ """
+ A handler class which writes logging records, appropriately formatted,
+ to a stream. Note that this class does not close the stream, as
+ sys.stdout or sys.stderr may be used.
+ """
+
+ terminator = '\n'
+
+ def __init__(self, stream=None):
+ """
+ Initialize the handler.
+
+ If stream is not specified, sys.stderr is used.
+ """
+ Handler.__init__(self)
+ if stream is None:
+ stream = sys.stderr
+ self.stream = stream
+
+ def flush(self):
+ """
+ Flushes the stream.
+ """
+ self.acquire()
+ try:
+ if self.stream and hasattr(self.stream, "flush"):
+ self.stream.flush()
+ finally:
+ self.release()
+
+ def emit(self, record):
+ """
+ Emit a record.
+
+ If a formatter is specified, it is used to format the record.
+ The record is then written to the stream with a trailing newline. If
+ exception information is present, it is formatted using
+ traceback.print_exception and appended to the stream. If the stream
+ has an 'encoding' attribute, it is used to determine how to do the
+ output to the stream.
+ """
+ try:
+ msg = self.format(record)
+ stream = self.stream
+ stream.write(msg)
+ stream.write(self.terminator)
+ self.flush()
+ except Exception:
+ self.handleError(record)
+
+ def __repr__(self):
+ level = getLevelName(self.level)
+ name = getattr(self.stream, 'name', '')
+ if name:
+ name += ' '
+ return '<%s %s(%s)>' % (self.__class__.__name__, name, level)
+
+
+class FileHandler(StreamHandler):
+ """
+ A handler class which writes formatted logging records to disk files.
+ """
+ def __init__(self, filename, mode='a', encoding=None, delay=False):
+ """
+ Open the specified file and use it as the stream for logging.
+ """
+ # Issue #27493: add support for Path objects to be passed in
+ # filename = os.fspath(filename)
+ #keep the absolute path, otherwise derived classes which use this
+ #may come a cropper when the current directory changes
+ self.baseFilename = os.path.abspath(filename)
+ self.mode = mode
+ self.encoding = encoding
+ self.delay = delay
+ if delay:
+ #We don't open the stream, but we still need to call the
+ #Handler constructor to set level, formatter, lock etc.
+ Handler.__init__(self)
+ self.stream = None
+ else:
+ StreamHandler.__init__(self, self._open())
+
+ def close(self):
+ """
+ Closes the stream.
+ """
+ self.acquire()
+ try:
+ try:
+ if self.stream:
+ try:
+ self.flush()
+ finally:
+ stream = self.stream
+ self.stream = None
+ if hasattr(stream, "close"):
+ stream.close()
+ finally:
+ # Issue #19523: call unconditionally to
+ # prevent a handler leak when delay is set
+ StreamHandler.close(self)
+ finally:
+ self.release()
+
+ def _open(self):
+ """
+ Open the current base file with the (original) mode and encoding.
+ Return the resulting stream.
+ """
+ return open(self.baseFilename, self.mode, encoding=self.encoding)
+
+ def emit(self, record):
+ """
+ Emit a record.
+
+ If the stream was not opened because 'delay' was specified in the
+ constructor, open it before calling the superclass's emit.
+ """
+ if self.stream is None:
+ self.stream = self._open()
+ StreamHandler.emit(self, record)
+
+ def __repr__(self):
+ level = getLevelName(self.level)
+ return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level)
+
+
+class _StderrHandler(StreamHandler):
+ """
+ This class is like a StreamHandler using sys.stderr, but always uses
+ whatever sys.stderr is currently set to rather than the value of
+ sys.stderr at handler construction time.
+ """
+ def __init__(self, level=NOTSET):
+ """
+ Initialize the handler.
+ """
+ Handler.__init__(self, level)
+
+ @property
+ def stream(self):
+ return sys.stderr
+
+
+_defaultLastResort = _StderrHandler(WARNING)
+lastResort = _defaultLastResort
+
+#---------------------------------------------------------------------------
+# Manager classes and functions
+#---------------------------------------------------------------------------
+
+class PlaceHolder(object):
+ """
+ PlaceHolder instances are used in the Manager logger hierarchy to take
+ the place of nodes for which no loggers have been defined. This class is
+ intended for internal use only and not as part of the public API.
+ """
+ def __init__(self, alogger):
+ """
+ Initialize with the specified logger being a child of this placeholder.
+ """
+ self.loggerMap = { alogger : None }
+
+ def append(self, alogger):
+ """
+ Add the specified logger as a child of this placeholder.
+ """
+ if alogger not in self.loggerMap:
+ self.loggerMap[alogger] = None
+
+#
+# Determine which class to use when instantiating loggers.
+#
+
+def setLoggerClass(klass):
+ """
+ Set the class to be used when instantiating a logger. The class should
+ define __init__() such that only a name argument is required, and the
+ __init__() should call Logger.__init__()
+ """
+ if klass != Logger:
+ if not issubclass(klass, Logger):
+ raise TypeError("logger not derived from logging.Logger: "
+ + klass.__name__)
+ global _loggerClass
+ _loggerClass = klass
+
+def getLoggerClass():
+ """
+ Return the class to be used when instantiating a logger.
+ """
+ return _loggerClass
+
+class Manager(object):
+ """
+ There is [under normal circumstances] just one Manager instance, which
+ holds the hierarchy of loggers.
+ """
+ def __init__(self, rootnode):
+ """
+ Initialize the manager with the root node of the logger hierarchy.
+ """
+ self.root = rootnode
+ self.disable = 0
+ self.emittedNoHandlerWarning = False
+ self.loggerDict = {}
+ self.loggerClass = None
+ self.logRecordFactory = None
+
+ def getLogger(self, name):
+ """
+ Get a logger with the specified name (channel name), creating it
+ if it doesn't yet exist. This name is a dot-separated hierarchical
+ name, such as "a", "a.b", "a.b.c" or similar.
+
+ If a PlaceHolder existed for the specified name [i.e. the logger
+ didn't exist but a child of it did], replace it with the created
+ logger and fix up the parent/child references which pointed to the
+ placeholder to now point to the logger.
+ """
+ rv = None
+ if not isinstance(name, str):
+ raise TypeError('A logger name must be a string')
+ _acquireLock()
+ try:
+ if name in self.loggerDict:
+ rv = self.loggerDict[name]
+ if isinstance(rv, PlaceHolder):
+ ph = rv
+ rv = (self.loggerClass or _loggerClass)(name)
+ rv.manager = self
+ self.loggerDict[name] = rv
+ self._fixupChildren(ph, rv)
+ self._fixupParents(rv)
+ else:
+ rv = (self.loggerClass or _loggerClass)(name)
+ rv.manager = self
+ self.loggerDict[name] = rv
+ self._fixupParents(rv)
+ finally:
+ _releaseLock()
+ return rv
+
+ def setLoggerClass(self, klass):
+ """
+ Set the class to be used when instantiating a logger with this Manager.
+ """
+ if klass != Logger:
+ if not issubclass(klass, Logger):
+ raise TypeError("logger not derived from logging.Logger: "
+ + klass.__name__)
+ self.loggerClass = klass
+
+ def setLogRecordFactory(self, factory):
+ """
+ Set the factory to be used when instantiating a log record with this
+ Manager.
+ """
+ self.logRecordFactory = factory
+
+ def _fixupParents(self, alogger):
+ """
+ Ensure that there are either loggers or placeholders all the way
+ from the specified logger to the root of the logger hierarchy.
+ """
+ name = alogger.name
+ i = name.rfind(".")
+ rv = None
+ while (i > 0) and not rv:
+ substr = name[:i]
+ if substr not in self.loggerDict:
+ self.loggerDict[substr] = PlaceHolder(alogger)
+ else:
+ obj = self.loggerDict[substr]
+ if isinstance(obj, Logger):
+ rv = obj
+ else:
+ assert isinstance(obj, PlaceHolder)
+ obj.append(alogger)
+ i = name.rfind(".", 0, i - 1)
+ if not rv:
+ rv = self.root
+ alogger.parent = rv
+
+ def _fixupChildren(self, ph, alogger):
+ """
+ Ensure that children of the placeholder ph are connected to the
+ specified logger.
+ """
+ name = alogger.name
+ namelen = len(name)
+ for c in ph.loggerMap.keys():
+ #The if means ... if not c.parent.name.startswith(nm)
+ if c.parent.name[:namelen] != name:
+ alogger.parent = c.parent
+ c.parent = alogger
+
+#---------------------------------------------------------------------------
+# Logger classes and functions
+#---------------------------------------------------------------------------
+
+class Logger(Filterer):
+ """
+ Instances of the Logger class represent a single logging channel. A
+ "logging channel" indicates an area of an application. Exactly how an
+ "area" is defined is up to the application developer. Since an
+ application can have any number of areas, logging channels are identified
+ by a unique string. Application areas can be nested (e.g. an area
+ of "input processing" might include sub-areas "read CSV files", "read
+ XLS files" and "read Gnumeric files"). To cater for this natural nesting,
+ channel names are organized into a namespace hierarchy where levels are
+ separated by periods, much like the Java or Python package namespace. So
+ in the instance given above, channel names might be "input" for the upper
+ level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
+ There is no arbitrary limit to the depth of nesting.
+ """
+ def __init__(self, name, level=NOTSET):
+ """
+ Initialize the logger with a name and an optional level.
+ """
+ Filterer.__init__(self)
+ self.name = name
+ self.level = _checkLevel(level)
+ self.parent = None
+ self.propagate = True
+ self.handlers = []
+ self.disabled = False
+
+ def setLevel(self, level):
+ """
+ Set the logging level of this logger. level must be an int or a str.
+ """
+ self.level = _checkLevel(level)
+
+ def debug(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'DEBUG'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
+ """
+ if self.isEnabledFor(DEBUG):
+ self._log(DEBUG, msg, args, **kwargs)
+
+ def info(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'INFO'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
+ """
+ if self.isEnabledFor(INFO):
+ self._log(INFO, msg, args, **kwargs)
+
+ def warning(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'WARNING'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
+ """
+ if self.isEnabledFor(WARNING):
+ self._log(WARNING, msg, args, **kwargs)
+
+ def warn(self, msg, *args, **kwargs):
+ warnings.warn("The 'warn' method is deprecated, "
+ "use 'warning' instead", DeprecationWarning, 2)
+ self.warning(msg, *args, **kwargs)
+
+ def error(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'ERROR'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.error("Houston, we have a %s", "major problem", exc_info=1)
+ """
+ if self.isEnabledFor(ERROR):
+ self._log(ERROR, msg, args, **kwargs)
+
+ def exception(self, msg, *args, exc_info=True, **kwargs):
+ """
+ Convenience method for logging an ERROR with exception information.
+ """
+ self.error(msg, *args, exc_info=exc_info, **kwargs)
+
+ def critical(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'CRITICAL'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
+ """
+ if self.isEnabledFor(CRITICAL):
+ self._log(CRITICAL, msg, args, **kwargs)
+
+ fatal = critical
+
+ def log(self, level, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with the integer severity 'level'.
+
+ To pass exception information, use the keyword argument exc_info with
+ a true value, e.g.
+
+ logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
+ """
+ if not isinstance(level, int):
+ if raiseExceptions:
+ raise TypeError("level must be an integer")
+ else:
+ return
+ if self.isEnabledFor(level):
+ self._log(level, msg, args, **kwargs)
+
+ def findCaller(self, stack_info=False):
+ """
+ Find the stack frame of the caller so that we can note the source
+ file name, line number and function name.
+ """
+ f = currentframe()
+ #On some versions of IronPython, currentframe() returns None if
+ #IronPython isn't run with -X:Frames.
+ if f is not None:
+ f = f.f_back
+ rv = "(unknown file)", 0, "(unknown function)", None
+ while hasattr(f, "f_code"):
+ co = f.f_code
+ filename = os.path.normcase(co.co_filename)
+ if filename == _srcfile:
+ f = f.f_back
+ continue
+ sinfo = None
+ if stack_info:
+ sio = io.StringIO()
+ sio.write('Stack (most recent call last):\n')
+ traceback.print_stack(f, file=sio)
+ sinfo = sio.getvalue()
+ if sinfo[-1] == '\n':
+ sinfo = sinfo[:-1]
+ sio.close()
+ rv = (co.co_filename, f.f_lineno, co.co_name, sinfo)
+ break
+ return rv
+
+ def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
+ func=None, extra=None, sinfo=None):
+ """
+ A factory method which can be overridden in subclasses to create
+ specialized LogRecords.
+ """
+ rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
+ sinfo)
+ if extra is not None:
+ for key in extra:
+ if (key in ["message", "asctime"]) or (key in rv.__dict__):
+ raise KeyError("Attempt to overwrite %r in LogRecord" % key)
+ rv.__dict__[key] = extra[key]
+ return rv
+
+ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
+ """
+ Low-level logging routine which creates a LogRecord and then calls
+ all the handlers of this logger to handle the record.
+ """
+ sinfo = None
+ if _srcfile:
+ #IronPython doesn't track Python frames, so findCaller raises an
+ #exception on some versions of IronPython. We trap it here so that
+ #IronPython can use logging.
+ try:
+ fn, lno, func, sinfo = self.findCaller(stack_info)
+ except ValueError: # pragma: no cover
+ fn, lno, func = "(unknown file)", 0, "(unknown function)"
+ else: # pragma: no cover
+ fn, lno, func = "(unknown file)", 0, "(unknown function)"
+ if exc_info:
+ if isinstance(exc_info, BaseException):
+ exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
+ elif not isinstance(exc_info, tuple):
+ exc_info = sys.exc_info()
+ record = self.makeRecord(self.name, level, fn, lno, msg, args,
+ exc_info, func, extra, sinfo)
+ self.handle(record)
+
+ def handle(self, record):
+ """
+ Call the handlers for the specified record.
+
+ This method is used for unpickled records received from a socket, as
+ well as those created locally. Logger-level filtering is applied.
+ """
+ if (not self.disabled) and self.filter(record):
+ self.callHandlers(record)
+
+ def addHandler(self, hdlr):
+ """
+ Add the specified handler to this logger.
+ """
+ _acquireLock()
+ try:
+ if not (hdlr in self.handlers):
+ self.handlers.append(hdlr)
+ finally:
+ _releaseLock()
+
+ def removeHandler(self, hdlr):
+ """
+ Remove the specified handler from this logger.
+ """
+ _acquireLock()
+ try:
+ if hdlr in self.handlers:
+ self.handlers.remove(hdlr)
+ finally:
+ _releaseLock()
+
+ def hasHandlers(self):
+ """
+ See if this logger has any handlers configured.
+
+ Loop through all handlers for this logger and its parents in the
+ logger hierarchy. Return True if a handler was found, else False.
+ Stop searching up the hierarchy whenever a logger with the "propagate"
+ attribute set to zero is found - that will be the last logger which
+ is checked for the existence of handlers.
+ """
+ c = self
+ rv = False
+ while c:
+ if c.handlers:
+ rv = True
+ break
+ if not c.propagate:
+ break
+ else:
+ c = c.parent
+ return rv
+
+ def callHandlers(self, record):
+ """
+ Pass a record to all relevant handlers.
+
+ Loop through all handlers for this logger and its parents in the
+ logger hierarchy. If no handler was found, output a one-off error
+ message to sys.stderr. Stop searching up the hierarchy whenever a
+ logger with the "propagate" attribute set to zero is found - that
+ will be the last logger whose handlers are called.
+ """
+ c = self
+ found = 0
+ while c:
+ for hdlr in c.handlers:
+ found = found + 1
+ if record.levelno >= hdlr.level:
+ hdlr.handle(record)
+ if not c.propagate:
+ c = None #break out
+ else:
+ c = c.parent
+ if (found == 0):
+ if lastResort:
+ if record.levelno >= lastResort.level:
+ lastResort.handle(record)
+ elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
+ sys.stderr.write("No handlers could be found for logger"
+ " \"%s\"\n" % self.name)
+ self.manager.emittedNoHandlerWarning = True
+
+ def getEffectiveLevel(self):
+ """
+ Get the effective level for this logger.
+
+ Loop through this logger and its parents in the logger hierarchy,
+ looking for a non-zero logging level. Return the first one found.
+ """
+ logger = self
+ while logger:
+ if logger.level:
+ return logger.level
+ logger = logger.parent
+ return NOTSET
+
+ def isEnabledFor(self, level):
+ """
+ Is this logger enabled for level 'level'?
+ """
+ if self.manager.disable >= level:
+ return False
+ return level >= self.getEffectiveLevel()
+
+ def getChild(self, suffix):
+ """
+ Get a logger which is a descendant to this one.
+
+ This is a convenience method, such that
+
+ logging.getLogger('abc').getChild('def.ghi')
+
+ is the same as
+
+ logging.getLogger('abc.def.ghi')
+
+ It's useful, for example, when the parent logger is named using
+ __name__ rather than a literal string.
+ """
+ if self.root is not self:
+ suffix = '.'.join((self.name, suffix))
+ return self.manager.getLogger(suffix)
+
+ def __repr__(self):
+ level = getLevelName(self.getEffectiveLevel())
+ return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
+
+
+class RootLogger(Logger):
+ """
+ A root logger is not that different to any other logger, except that
+ it must have a logging level and there is only one instance of it in
+ the hierarchy.
+ """
+ def __init__(self, level):
+ """
+ Initialize the logger with the name "root".
+ """
+ Logger.__init__(self, "root", level)
+
+_loggerClass = Logger
+
+class LoggerAdapter(object):
+ """
+ An adapter for loggers which makes it easier to specify contextual
+ information in logging output.
+ """
+
+ def __init__(self, logger, extra):
+ """
+ Initialize the adapter with a logger and a dict-like object which
+ provides contextual information. This constructor signature allows
+ easy stacking of LoggerAdapters, if so desired.
+
+ You can effectively pass keyword arguments as shown in the
+ following example:
+
+ adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
+ """
+ self.logger = logger
+ self.extra = extra
+
+ def process(self, msg, kwargs):
+ """
+ Process the logging message and keyword arguments passed in to
+ a logging call to insert contextual information. You can either
+ manipulate the message itself, the keyword args or both. Return
+ the message and kwargs modified (or not) to suit your needs.
+
+ Normally, you'll only need to override this one method in a
+ LoggerAdapter subclass for your specific needs.
+ """
+ kwargs["extra"] = self.extra
+ return msg, kwargs
+
+ #
+ # Boilerplate convenience methods
+ #
+ def debug(self, msg, *args, **kwargs):
+ """
+ Delegate a debug call to the underlying logger.
+ """
+ self.log(DEBUG, msg, *args, **kwargs)
+
+ def info(self, msg, *args, **kwargs):
+ """
+ Delegate an info call to the underlying logger.
+ """
+ self.log(INFO, msg, *args, **kwargs)
+
+ def warning(self, msg, *args, **kwargs):
+ """
+ Delegate a warning call to the underlying logger.
+ """
+ self.log(WARNING, msg, *args, **kwargs)
+
+ def warn(self, msg, *args, **kwargs):
+ warnings.warn("The 'warn' method is deprecated, "
+ "use 'warning' instead", DeprecationWarning, 2)
+ self.warning(msg, *args, **kwargs)
+
+ def error(self, msg, *args, **kwargs):
+ """
+ Delegate an error call to the underlying logger.
+ """
+ self.log(ERROR, msg, *args, **kwargs)
+
+ def exception(self, msg, *args, exc_info=True, **kwargs):
+ """
+ Delegate an exception call to the underlying logger.
+ """
+ self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)
+
+ def critical(self, msg, *args, **kwargs):
+ """
+ Delegate a critical call to the underlying logger.
+ """
+ self.log(CRITICAL, msg, *args, **kwargs)
+
+ def log(self, level, msg, *args, **kwargs):
+ """
+ Delegate a log call to the underlying logger, after adding
+ contextual information from this adapter instance.
+ """
+ if self.isEnabledFor(level):
+ msg, kwargs = self.process(msg, kwargs)
+ self.logger.log(level, msg, *args, **kwargs)
+
+ def isEnabledFor(self, level):
+ """
+ Is this logger enabled for level 'level'?
+ """
+ if self.logger.manager.disable >= level:
+ return False
+ return level >= self.getEffectiveLevel()
+
+ def setLevel(self, level):
+ """
+ Set the specified level on the underlying logger.
+ """
+ self.logger.setLevel(level)
+
+ def getEffectiveLevel(self):
+ """
+ Get the effective level for the underlying logger.
+ """
+ return self.logger.getEffectiveLevel()
+
+ def hasHandlers(self):
+ """
+ See if the underlying logger has any handlers.
+ """
+ return self.logger.hasHandlers()
+
+ def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
+ """
+ Low-level log implementation, proxied to allow nested logger adapters.
+ """
+ return self.logger._log(
+ level,
+ msg,
+ args,
+ exc_info=exc_info,
+ extra=extra,
+ stack_info=stack_info,
+ )
+
+ @property
+ def manager(self):
+ return self.logger.manager
+
+ @manager.setter
+ def manager(self, value):
+ self.logger.manager = value
+
+ @property
+ def name(self):
+ return self.logger.name
+
+ def __repr__(self):
+ logger = self.logger
+ level = getLevelName(logger.getEffectiveLevel())
+ return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level)
+
+root = RootLogger(WARNING)
+Logger.root = root
+Logger.manager = Manager(Logger.root)
+
+#---------------------------------------------------------------------------
+# Configuration classes and functions
+#---------------------------------------------------------------------------
+
+def basicConfig(**kwargs):
+ """
+ Do basic configuration for the logging system.
+
+ This function does nothing if the root logger already has handlers
+ configured. It is a convenience method intended for use by simple scripts
+ to do one-shot configuration of the logging package.
+
+ The default behaviour is to create a StreamHandler which writes to
+ sys.stderr, set a formatter using the BASIC_FORMAT format string, and
+ add the handler to the root logger.
+
+ A number of optional keyword arguments may be specified, which can alter
+ the default behaviour.
+
+ filename Specifies that a FileHandler be created, using the specified
+ filename, rather than a StreamHandler.
+ filemode Specifies the mode to open the file, if filename is specified
+ (if filemode is unspecified, it defaults to 'a').
+ format Use the specified format string for the handler.
+ datefmt Use the specified date/time format.
+ style If a format string is specified, use this to specify the
+ type of format string (possible values '%', '{', '$', for
+ %-formatting, :meth:`str.format` and :class:`string.Template`
+ - defaults to '%').
+ level Set the root logger level to the specified level.
+ stream Use the specified stream to initialize the StreamHandler. Note
+ that this argument is incompatible with 'filename' - if both
+ are present, 'stream' is ignored.
+ handlers If specified, this should be an iterable of already created
+ handlers, which will be added to the root handler. Any handler
+ in the list which does not have a formatter assigned will be
+ assigned the formatter created in this function.
+
+ Note that you could specify a stream created using open(filename, mode)
+ rather than passing the filename and mode in. However, it should be
+ remembered that StreamHandler does not close its stream (since it may be
+ using sys.stdout or sys.stderr), whereas FileHandler closes its stream
+ when the handler is closed.
+
+ .. versionchanged:: 3.2
+ Added the ``style`` parameter.
+
+ .. versionchanged:: 3.3
+ Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
+ incompatible arguments (e.g. ``handlers`` specified together with
+ ``filename``/``filemode``, or ``filename``/``filemode`` specified
+ together with ``stream``, or ``handlers`` specified together with
+ ``stream``.
+ """
+ # Add thread safety in case someone mistakenly calls
+ # basicConfig() from multiple threads
+ _acquireLock()
+ try:
+ if len(root.handlers) == 0:
+ handlers = kwargs.pop("handlers", None)
+ if handlers is None:
+ if "stream" in kwargs and "filename" in kwargs:
+ raise ValueError("'stream' and 'filename' should not be "
+ "specified together")
+ else:
+ if "stream" in kwargs or "filename" in kwargs:
+ raise ValueError("'stream' or 'filename' should not be "
+ "specified together with 'handlers'")
+ if handlers is None:
+ filename = kwargs.pop("filename", None)
+ mode = kwargs.pop("filemode", 'a')
+ if filename:
+ h = FileHandler(filename, mode)
+ else:
+ stream = kwargs.pop("stream", None)
+ h = StreamHandler(stream)
+ handlers = [h]
+ dfs = kwargs.pop("datefmt", None)
+ style = kwargs.pop("style", '%')
+ if style not in _STYLES:
+ raise ValueError('Style must be one of: %s' % ','.join(
+ _STYLES.keys()))
+ fs = kwargs.pop("format", _STYLES[style][1])
+ fmt = Formatter(fs, dfs, style)
+ for h in handlers:
+ if h.formatter is None:
+ h.setFormatter(fmt)
+ root.addHandler(h)
+ level = kwargs.pop("level", None)
+ if level is not None:
+ root.setLevel(level)
+ if kwargs:
+ keys = ', '.join(kwargs.keys())
+ raise ValueError('Unrecognised argument(s): %s' % keys)
+ finally:
+ _releaseLock()
+
+#---------------------------------------------------------------------------
+# Utility functions at module level.
+# Basically delegate everything to the root logger.
+#---------------------------------------------------------------------------
+
+def getLogger(name=None):
+ """
+ Return a logger with the specified name, creating it if necessary.
+
+ If no name is specified, return the root logger.
+ """
+ if name:
+ return Logger.manager.getLogger(name)
+ else:
+ return root
+
+def critical(msg, *args, **kwargs):
+ """
+ Log a message with severity 'CRITICAL' on the root logger. If the logger
+ has no handlers, call basicConfig() to add a console handler with a
+ pre-defined format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.critical(msg, *args, **kwargs)
+
+fatal = critical
+
+def error(msg, *args, **kwargs):
+ """
+ Log a message with severity 'ERROR' on the root logger. If the logger has
+ no handlers, call basicConfig() to add a console handler with a pre-defined
+ format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.error(msg, *args, **kwargs)
+
+def exception(msg, *args, exc_info=True, **kwargs):
+ """
+ Log a message with severity 'ERROR' on the root logger, with exception
+ information. If the logger has no handlers, basicConfig() is called to add
+ a console handler with a pre-defined format.
+ """
+ error(msg, *args, exc_info=exc_info, **kwargs)
+
+def warning(msg, *args, **kwargs):
+ """
+ Log a message with severity 'WARNING' on the root logger. If the logger has
+ no handlers, call basicConfig() to add a console handler with a pre-defined
+ format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.warning(msg, *args, **kwargs)
+
+def warn(msg, *args, **kwargs):
+ warnings.warn("The 'warn' function is deprecated, "
+ "use 'warning' instead", DeprecationWarning, 2)
+ warning(msg, *args, **kwargs)
+
+def info(msg, *args, **kwargs):
+ """
+ Log a message with severity 'INFO' on the root logger. If the logger has
+ no handlers, call basicConfig() to add a console handler with a pre-defined
+ format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.info(msg, *args, **kwargs)
+
+def debug(msg, *args, **kwargs):
+ """
+ Log a message with severity 'DEBUG' on the root logger. If the logger has
+ no handlers, call basicConfig() to add a console handler with a pre-defined
+ format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.debug(msg, *args, **kwargs)
+
+def log(level, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with the integer severity 'level' on the root logger. If
+ the logger has no handlers, call basicConfig() to add a console handler
+ with a pre-defined format.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ root.log(level, msg, *args, **kwargs)
+
+def disable(level):
+ """
+ Disable all logging calls of severity 'level' and below.
+ """
+ root.manager.disable = level
+
+def shutdown(handlerList=_handlerList):
+ """
+ Perform any cleanup actions in the logging system (e.g. flushing
+ buffers).
+
+ Should be called at application exit.
+ """
+ for wr in reversed(handlerList[:]):
+ #errors might occur, for example, if files are locked
+ #we just ignore them if raiseExceptions is not set
+ try:
+ h = wr()
+ if h:
+ try:
+ h.acquire()
+ h.flush()
+ h.close()
+ except (OSError, ValueError):
+ # Ignore errors which might be caused
+ # because handlers have been closed but
+ # references to them are still around at
+ # application exit.
+ pass
+ finally:
+ h.release()
+ except: # ignore everything, as we're shutting down
+ if raiseExceptions:
+ raise
+ #else, swallow
+
+#Let's try and shutdown automatically on application exit...
+import atexit
+atexit.register(shutdown)
+
+# Null handler
+
+class NullHandler(Handler):
+ """
+ This handler does nothing. It's intended to be used to avoid the
+ "No handlers could be found for logger XXX" one-off warning. This is
+ important for library code, which may contain code to log events. If a user
+ of the library does not configure logging, the one-off warning might be
+ produced; to avoid this, the library developer simply needs to instantiate
+ a NullHandler and add it to the top-level logger of the library module or
+ package.
+ """
+ def handle(self, record):
+ """Stub."""
+
+ def emit(self, record):
+ """Stub."""
+
+ def createLock(self):
+ self.lock = None
+
+# Warnings integration
+
+_warnings_showwarning = None
+
+def _showwarning(message, category, filename, lineno, file=None, line=None):
+ """
+ Implementation of showwarnings which redirects to logging, which will first
+ check to see if the file parameter is None. If a file is specified, it will
+ delegate to the original warnings implementation of showwarning. Otherwise,
+ it will call warnings.formatwarning and will log the resulting string to a
+ warnings logger named "py.warnings" with level logging.WARNING.
+ """
+ if file is not None:
+ if _warnings_showwarning is not None:
+ _warnings_showwarning(message, category, filename, lineno, file, line)
+ else:
+ s = warnings.formatwarning(message, category, filename, lineno, line)
+ logger = getLogger("py.warnings")
+ if not logger.handlers:
+ logger.addHandler(NullHandler())
+ logger.warning("%s", s)
+
+def captureWarnings(capture):
+ """
+ If capture is true, redirect all warnings to the logging package.
+ If capture is False, ensure that warnings are not redirected to logging
+ but to their original destinations.
+ """
+ global _warnings_showwarning
+ if capture:
+ if _warnings_showwarning is None:
+ _warnings_showwarning = warnings.showwarning
+ warnings.showwarning = _showwarning
+ else:
+ if _warnings_showwarning is not None:
+ warnings.showwarning = _warnings_showwarning
+ _warnings_showwarning = None
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ntpath.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ntpath.py
new file mode 100644
index 00000000..d1ffb774
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/ntpath.py
@@ -0,0 +1,568 @@
+
+# Module 'ntpath' -- common operations on WinNT/Win95 and UEFI pathnames.
+#
+# Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+# Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+"""Common pathname manipulations, WindowsNT/95 and UEFI version.
+
+Instead of importing this module directly, import os and refer to this
+module as os.path.
+"""
+
+import os
+import sys
+import stat
+import genericpath
+import warnings
+
+from genericpath import *
+from genericpath import _unicode
+
+__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
+ "basename","dirname","commonprefix","getsize","getmtime",
+ "getatime","getctime", "islink","exists","lexists","isdir","isfile",
+ "ismount","walk","expanduser","expandvars","normpath","abspath",
+ "splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
+ "extsep","devnull","realpath","supports_unicode_filenames","relpath"]
+
+# strings representing various path-related bits and pieces
+curdir = '.'
+pardir = '..'
+extsep = '.'
+sep = '\\'
+pathsep = ';'
+altsep = '/'
+defpath = '.;C:\\bin'
+if 'ce' in sys.builtin_module_names:
+ defpath = '\\Windows'
+elif 'os2' in sys.builtin_module_names:
+ # OS/2 w/ VACPP
+ altsep = '/'
+devnull = 'nul'
+
+# Normalize the case of a pathname and map slashes to backslashes.
+# Other normalizations (such as optimizing '../' away) are not done
+# (this is done by normpath).
+
+def normcase(s):
+ """Normalize case of pathname.
+
+ Makes all characters lowercase and all slashes into backslashes."""
+ return s.replace("/", "\\").lower()
+
+
+# Return whether a path is absolute.
+# Trivial in Posix, harder on the Mac or MS-DOS.
+# For DOS it is absolute if it starts with a slash or backslash (current
+# volume), or if a pathname after the volume letter and colon / UNC resource
+# starts with a slash or backslash.
+
+def isabs(s):
+ """Test whether a path is absolute"""
+ s = splitdrive(s)[1]
+ return s != '' and s[:1] in '/\\'
+
+
+# Join two (or more) paths.
+def join(path, *paths):
+ """Join two or more pathname components, inserting "\\" as needed."""
+ result_drive, result_path = splitdrive(path)
+ for p in paths:
+ p_drive, p_path = splitdrive(p)
+ if p_path and p_path[0] in '\\/':
+ # Second path is absolute
+ if p_drive or not result_drive:
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ elif p_drive and p_drive != result_drive:
+ if p_drive.lower() != result_drive.lower():
+ # Different drives => ignore the first path entirely
+ result_drive = p_drive
+ result_path = p_path
+ continue
+ # Same drive in different case
+ result_drive = p_drive
+ # Second path is relative to the first
+ if result_path and result_path[-1] not in '\\/':
+ result_path = result_path + '\\'
+ result_path = result_path + p_path
+ ## add separator between UNC and non-absolute path
+ if (result_path and result_path[0] not in '\\/' and
+ result_drive and result_drive[-1:] != ':'):
+ return result_drive + sep + result_path
+ return result_drive + result_path
+
+
+# Split a path in a drive specification (a drive letter followed by a
+# colon) and the path specification.
+# It is always true that drivespec + pathspec == p
+# NOTE: for UEFI (and even Windows) you can have multiple characters to the left
+# of the ':' for the device or drive spec. This is reflected in the modifications
+# to splitdrive() and splitunc().
+def splitdrive(p):
+ """Split a pathname into drive/UNC sharepoint and relative path specifiers.
+ Returns a 2-tuple (drive_or_unc, path); either part may be empty.
+
+ If you assign
+ result = splitdrive(p)
+ It is always true that:
+ result[0] + result[1] == p
+
+ If the path contained a drive letter, drive_or_unc will contain everything
+ up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")
+
+ If the path contained a UNC path, the drive_or_unc will contain the host name
+ and share up to but not including the fourth directory separator character.
+ e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")
+
+ Paths cannot contain both a drive letter and a UNC path.
+
+ """
+ if len(p) > 1:
+ normp = p.replace(altsep, sep)
+ if (normp[0:2] == sep*2) and (normp[2:3] != sep):
+ # is a UNC path:
+ # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
+ # \\machine\mountpoint\directory\etc\...
+ # directory ^^^^^^^^^^^^^^^
+ index = normp.find(sep, 2)
+ if index == -1:
+ return '', p
+ index2 = normp.find(sep, index + 1)
+ # a UNC path can't have two slashes in a row
+ # (after the initial two)
+ if index2 == index + 1:
+ return '', p
+ if index2 == -1:
+ index2 = len(p)
+ return p[:index2], p[index2:]
+ index = p.find(':')
+ if index != -1:
+ index = index + 1
+ return p[:index], p[index:]
+ return '', p
+
+# Parse UNC paths
+def splitunc(p):
+ """Split a pathname into UNC mount point and relative path specifiers.
+
+ Return a 2-tuple (unc, rest); either part may be empty.
+ If unc is not empty, it has the form '//host/mount' (or similar
+ using backslashes). unc+rest is always the input path.
+ Paths containing drive letters never have an UNC part.
+ """
+ if ':' in p:
+ return '', p # Drive letter or device name present
+ firstTwo = p[0:2]
+ if firstTwo == '//' or firstTwo == '\\\\':
+ # is a UNC path:
+ # vvvvvvvvvvvvvvvvvvvv equivalent to drive letter
+ # \\machine\mountpoint\directories...
+ # directory ^^^^^^^^^^^^^^^
+ normp = p.replace('\\', '/')
+ index = normp.find('/', 2)
+ if index <= 2:
+ return '', p
+ index2 = normp.find('/', index + 1)
+ # a UNC path can't have two slashes in a row
+ # (after the initial two)
+ if index2 == index + 1:
+ return '', p
+ if index2 == -1:
+ index2 = len(p)
+ return p[:index2], p[index2:]
+ return '', p
+
+
+# Split a path in head (everything up to the last '/') and tail (the
+# rest). After the trailing '/' is stripped, the invariant
+# join(head, tail) == p holds.
+# The resulting head won't end in '/' unless it is the root.
+
+def split(p):
+ """Split a pathname.
+
+ Return tuple (head, tail) where tail is everything after the final slash.
+ Either part may be empty."""
+
+ d, p = splitdrive(p)
+ # set i to index beyond p's last slash
+ i = len(p)
+ while i and p[i-1] not in '/\\':
+ i = i - 1
+ head, tail = p[:i], p[i:] # now tail has no slashes
+ # remove trailing slashes from head, unless it's all slashes
+ head2 = head
+ while head2 and head2[-1] in '/\\':
+ head2 = head2[:-1]
+ head = head2 or head
+ return d + head, tail
+
+
+# Split a path in root and extension.
+# The extension is everything starting at the last dot in the last
+# pathname component; the root is everything before that.
+# It is always true that root + ext == p.
+
+def splitext(p):
+ return genericpath._splitext(p, sep, altsep, extsep)
+splitext.__doc__ = genericpath._splitext.__doc__
+
+
+# Return the tail (basename) part of a path.
+
+def basename(p):
+ """Returns the final component of a pathname"""
+ return split(p)[1]
+
+
+# Return the head (dirname) part of a path.
+
+def dirname(p):
+ """Returns the directory component of a pathname"""
+ return split(p)[0]
+
+# Is a path a symbolic link?
+# This will always return false on systems where posix.lstat doesn't exist.
+
+def islink(path):
+ """Test for symbolic link.
+ On WindowsNT/95 and OS/2 always returns false
+ """
+ return False
+
+# alias exists to lexists
+lexists = exists
+
+# Is a path a mount point? Either a root (with or without drive letter)
+# or an UNC path with at most a / or \ after the mount point.
+
+def ismount(path):
+ """Test whether a path is a mount point (defined as root of drive)"""
+ unc, rest = splitunc(path)
+ if unc:
+ return rest in ("", "/", "\\")
+ p = splitdrive(path)[1]
+ return len(p) == 1 and p[0] in '/\\'
+
+
+# Directory tree walk.
+# For each directory under top (including top itself, but excluding
+# '.' and '..'), func(arg, dirname, filenames) is called, where
+# dirname is the name of the directory and filenames is the list
+# of files (and subdirectories etc.) in the directory.
+# The func may modify the filenames list, to implement a filter,
+# or to impose a different order of visiting.
+
+def walk(top, func, arg):
+ """Directory tree walk with callback function.
+
+ For each directory in the directory tree rooted at top (including top
+ itself, but excluding '.' and '..'), call func(arg, dirname, fnames).
+ dirname is the name of the directory, and fnames a list of the names of
+ the files and subdirectories in dirname (excluding '.' and '..'). func
+ may modify the fnames list in-place (e.g. via del or slice assignment),
+ and walk will only recurse into the subdirectories whose names remain in
+ fnames; this can be used to implement a filter, or to impose a specific
+ order of visiting. No semantics are defined for, or required of, arg,
+ beyond that arg is always passed to func. It can be used, e.g., to pass
+ a filename pattern, or a mutable object designed to accumulate
+ statistics. Passing None for arg is common."""
+ warnings.warnpy3k("In 3.x, os.path.walk is removed in favor of os.walk.",
+ stacklevel=2)
+ try:
+ names = os.listdir(top)
+ except os.error:
+ return
+ func(arg, top, names)
+ for name in names:
+ name = join(top, name)
+ if isdir(name):
+ walk(name, func, arg)
+
+
+# Expand paths beginning with '~' or '~user'.
+# '~' means $HOME; '~user' means that user's home directory.
+# If the path doesn't begin with '~', or if the user or $HOME is unknown,
+# the path is returned unchanged (leaving error reporting to whatever
+# function is called with the expanded path as argument).
+# See also module 'glob' for expansion of *, ? and [...] in pathnames.
+# (A function should also be defined to do full *sh-style environment
+# variable expansion.)
+
+def expanduser(path):
+ """Expand ~ and ~user constructs.
+
+ If user or $HOME is unknown, do nothing."""
+ if path[:1] != '~':
+ return path
+ i, n = 1, len(path)
+ while i < n and path[i] not in '/\\':
+ i = i + 1
+
+ if 'HOME' in os.environ:
+ userhome = os.environ['HOME']
+ elif 'USERPROFILE' in os.environ:
+ userhome = os.environ['USERPROFILE']
+ elif not 'HOMEPATH' in os.environ:
+ return path
+ else:
+ try:
+ drive = os.environ['HOMEDRIVE']
+ except KeyError:
+ drive = ''
+ userhome = join(drive, os.environ['HOMEPATH'])
+
+ if i != 1: #~user
+ userhome = join(dirname(userhome), path[1:i])
+
+ return userhome + path[i:]
+
+
+# Expand paths containing shell variable substitutions.
+# The following rules apply:
+# - no expansion within single quotes
+# - '$$' is translated into '$'
+# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
+# - ${varname} is accepted.
+# - $varname is accepted.
+# - %varname% is accepted.
+# - varnames can be made out of letters, digits and the characters '_-'
+# (though is not verified in the ${varname} and %varname% cases)
+# XXX With COMMAND.COM you can use any characters in a variable name,
+# XXX except '^|<>='.
+
+def expandvars(path):
+ """Expand shell variables of the forms $var, ${var} and %var%.
+
+ Unknown variables are left unchanged."""
+ if '$' not in path and '%' not in path:
+ return path
+ import string
+ varchars = string.ascii_letters + string.digits + '_-'
+ if isinstance(path, _unicode):
+ encoding = sys.getfilesystemencoding()
+ def getenv(var):
+ return os.environ[var.encode(encoding)].decode(encoding)
+ else:
+ def getenv(var):
+ return os.environ[var]
+ res = ''
+ index = 0
+ pathlen = len(path)
+ while index < pathlen:
+ c = path[index]
+ if c == '\'': # no expansion within single quotes
+ path = path[index + 1:]
+ pathlen = len(path)
+ try:
+ index = path.index('\'')
+ res = res + '\'' + path[:index + 1]
+ except ValueError:
+ res = res + c + path
+ index = pathlen - 1
+ elif c == '%': # variable or '%'
+ if path[index + 1:index + 2] == '%':
+ res = res + c
+ index = index + 1
+ else:
+ path = path[index+1:]
+ pathlen = len(path)
+ try:
+ index = path.index('%')
+ except ValueError:
+ res = res + '%' + path
+ index = pathlen - 1
+ else:
+ var = path[:index]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '%' + var + '%'
+ elif c == '$': # variable or '$$'
+ if path[index + 1:index + 2] == '$':
+ res = res + c
+ index = index + 1
+ elif path[index + 1:index + 2] == '{':
+ path = path[index+2:]
+ pathlen = len(path)
+ try:
+ index = path.index('}')
+ var = path[:index]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '${' + var + '}'
+ except ValueError:
+ res = res + '${' + path
+ index = pathlen - 1
+ else:
+ var = ''
+ index = index + 1
+ c = path[index:index + 1]
+ while c != '' and c in varchars:
+ var = var + c
+ index = index + 1
+ c = path[index:index + 1]
+ try:
+ res = res + getenv(var)
+ except KeyError:
+ res = res + '$' + var
+ if c != '':
+ index = index - 1
+ else:
+ res = res + c
+ index = index + 1
+ return res
+
+
+# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
+# Previously, this function also truncated pathnames to 8+3 format,
+# but as this module is called "ntpath", that's obviously wrong!
+
+def normpath(path):
+ """Normalize path, eliminating double slashes, etc."""
+ # Preserve unicode (if path is unicode)
+ backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')
+ if path.startswith(('\\\\.\\', '\\\\?\\')):
+ # in the case of paths with these prefixes:
+ # \\.\ -> device names
+ # \\?\ -> literal paths
+ # do not do any normalization, but return the path unchanged
+ return path
+ path = path.replace("/", "\\")
+ prefix, path = splitdrive(path)
+ # We need to be careful here. If the prefix is empty, and the path starts
+ # with a backslash, it could either be an absolute path on the current
+ # drive (\dir1\dir2\file) or a UNC filename (\\server\mount\dir1\file). It
+ # is therefore imperative NOT to collapse multiple backslashes blindly in
+ # that case.
+ # The code below preserves multiple backslashes when there is no drive
+ # letter. This means that the invalid filename \\\a\b is preserved
+ # unchanged, where a\\\b is normalised to a\b. It's not clear that there
+ # is any better behaviour for such edge cases.
+ if prefix == '':
+ # No drive letter - preserve initial backslashes
+ while path[:1] == "\\":
+ prefix = prefix + backslash
+ path = path[1:]
+ else:
+ # We have a drive letter - collapse initial backslashes
+ if path.startswith("\\"):
+ prefix = prefix + backslash
+ path = path.lstrip("\\")
+ comps = path.split("\\")
+ i = 0
+ while i < len(comps):
+ if comps[i] in ('.', ''):
+ del comps[i]
+ elif comps[i] == '..':
+ if i > 0 and comps[i-1] != '..':
+ del comps[i-1:i+1]
+ i -= 1
+ elif i == 0 and prefix.endswith("\\"):
+ del comps[i]
+ else:
+ i += 1
+ else:
+ i += 1
+ # If the path is now empty, substitute '.'
+ if not prefix and not comps:
+ comps.append(dot)
+ return prefix + backslash.join(comps)
+
+
+# Return an absolute path.
+try:
+ from nt import _getfullpathname
+
+except ImportError: # not running on Windows - mock up something sensible
+ def abspath(path):
+ """Return the absolute version of a path."""
+ if not isabs(path):
+ if isinstance(path, _unicode):
+ cwd = os.getcwdu()
+ else:
+ cwd = os.getcwd()
+ path = join(cwd, path)
+ return normpath(path)
+
+else: # use native Windows method on Windows
+ def abspath(path):
+ """Return the absolute version of a path."""
+
+ if path: # Empty path must return current working directory.
+ try:
+ path = _getfullpathname(path)
+ except WindowsError:
+ pass # Bad path - return unchanged.
+ elif isinstance(path, _unicode):
+ path = os.getcwdu()
+ else:
+ path = os.getcwd()
+ return normpath(path)
+
+# realpath is a no-op on systems without islink support
+realpath = abspath
+# Win9x family and earlier have no Unicode filename support.
+supports_unicode_filenames = (hasattr(sys, "getwindowsversion") and
+ sys.getwindowsversion()[3] >= 2)
+
+def _abspath_split(path):
+ abs = abspath(normpath(path))
+ prefix, rest = splitunc(abs)
+ is_unc = bool(prefix)
+ if not is_unc:
+ prefix, rest = splitdrive(abs)
+ return is_unc, prefix, [x for x in rest.split(sep) if x]
+
+def relpath(path, start=curdir):
+ """Return a relative version of a path"""
+
+ if not path:
+ raise ValueError("no path specified")
+
+ start_is_unc, start_prefix, start_list = _abspath_split(start)
+ path_is_unc, path_prefix, path_list = _abspath_split(path)
+
+ if path_is_unc ^ start_is_unc:
+ raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)"
+ % (path, start))
+ if path_prefix.lower() != start_prefix.lower():
+ if path_is_unc:
+ raise ValueError("path is on UNC root %s, start on UNC root %s"
+ % (path_prefix, start_prefix))
+ else:
+ raise ValueError("path is on drive %s, start on drive %s"
+ % (path_prefix, start_prefix))
+ # Work out how much of the filepath is shared by start and path.
+ i = 0
+ for e1, e2 in zip(start_list, path_list):
+ if e1.lower() != e2.lower():
+ break
+ i += 1
+
+ rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
+ if not rel_list:
+ return curdir
+ return join(*rel_list)
+
+try:
+ # The genericpath.isdir implementation uses os.stat and checks the mode
+ # attribute to tell whether or not the path is a directory.
+ # This is overkill on Windows - just pass the path to GetFileAttributes
+ # and check the attribute from there.
+ from nt import _isdir as isdir
+except ImportError:
+ # Use genericpath.isdir as imported above.
+ pass
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/os.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/os.py
new file mode 100644
index 00000000..b163199f
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/os.py
@@ -0,0 +1,792 @@
+
+# Module 'os' -- OS routines for NT, Posix, or UEFI depending on what system we're on.
+#
+# Copyright (c) 2015, Daryl McDaniel. All rights reserved.<BR>
+# Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License that accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+r"""OS routines for NT, Posix, or UEFI depending on what system we're on.
+
+This exports:
+ - all functions from edk2, posix, nt, os2, or ce, e.g. unlink, stat, etc.
+ - os.path is one of the modules uefipath, posixpath, or ntpath
+ - os.name is 'edk2', 'posix', 'nt', 'os2', 'ce' or 'riscos'
+ - os.curdir is a string representing the current directory ('.' or ':')
+ - os.pardir is a string representing the parent directory ('..' or '::')
+ - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
+ - os.extsep is the extension separator ('.' or '/')
+ - os.altsep is the alternate pathname separator (None or '/')
+ - os.pathsep is the component separator used in $PATH etc
+ - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
+ - os.defpath is the default search path for executables
+ - os.devnull is the file path of the null device ('/dev/null', etc.)
+
+Programs that import and use 'os' stand a better chance of being
+portable between different platforms. Of course, they must then
+only use functions that are defined by all platforms (e.g., unlink
+and opendir), and leave all pathname manipulation to os.path
+(e.g., split and join).
+"""
+
+#'
+
+import sys, errno
+
+_names = sys.builtin_module_names
+
+# Note: more names are added to __all__ later.
+__all__ = ["altsep", "curdir", "pardir", "sep", "extsep", "pathsep", "linesep",
+ "defpath", "name", "path", "devnull",
+ "SEEK_SET", "SEEK_CUR", "SEEK_END"]
+
+def _get_exports_list(module):
+ try:
+ return list(module.__all__)
+ except AttributeError:
+ return [n for n in dir(module) if n[0] != '_']
+
+if 'posix' in _names:
+ name = 'posix'
+ linesep = '\n'
+ from posix import *
+ try:
+ from posix import _exit
+ except ImportError:
+ pass
+ import posixpath as path
+
+ import posix
+ __all__.extend(_get_exports_list(posix))
+ del posix
+
+elif 'nt' in _names:
+ name = 'nt'
+ linesep = '\r\n'
+ from nt import *
+ try:
+ from nt import _exit
+ except ImportError:
+ pass
+ import ntpath as path
+
+ import nt
+ __all__.extend(_get_exports_list(nt))
+ del nt
+
+elif 'os2' in _names:
+ name = 'os2'
+ linesep = '\r\n'
+ from os2 import *
+ try:
+ from os2 import _exit
+ except ImportError:
+ pass
+ if sys.version.find('EMX GCC') == -1:
+ import ntpath as path
+ else:
+ import os2emxpath as path
+ from _emx_link import link
+
+ import os2
+ __all__.extend(_get_exports_list(os2))
+ del os2
+
+elif 'ce' in _names:
+ name = 'ce'
+ linesep = '\r\n'
+ from ce import *
+ try:
+ from ce import _exit
+ except ImportError:
+ pass
+ # We can use the standard Windows path.
+ import ntpath as path
+
+ import ce
+ __all__.extend(_get_exports_list(ce))
+ del ce
+
+elif 'riscos' in _names:
+ name = 'riscos'
+ linesep = '\n'
+ from riscos import *
+ try:
+ from riscos import _exit
+ except ImportError:
+ pass
+ import riscospath as path
+
+ import riscos
+ __all__.extend(_get_exports_list(riscos))
+ del riscos
+
+elif 'edk2' in _names:
+ name = 'edk2'
+ linesep = '\n'
+ from edk2 import *
+ try:
+ from edk2 import _exit
+ except ImportError:
+ pass
+ import ntpath as path
+ path.defpath = '.;/efi/tools/'
+
+ import edk2
+ __all__.extend(_get_exports_list(edk2))
+ del edk2
+
+else:
+ raise ImportError('no os specific module found')
+
+sys.modules['os.path'] = path
+from os.path import (curdir, pardir, sep, pathsep, defpath, extsep, altsep,
+ devnull)
+
+del _names
+
+# Python uses fixed values for the SEEK_ constants; they are mapped
+# to native constants if necessary in posixmodule.c
+SEEK_SET = 0
+SEEK_CUR = 1
+SEEK_END = 2
+
+#'
+
+# Super directory utilities.
+# (Inspired by Eric Raymond; the doc strings are mostly his)
+
+def makedirs(name, mode=777):
+ """makedirs(path [, mode=0777])
+
+ Super-mkdir; create a leaf directory and all intermediate ones.
+ Works like mkdir, except that any intermediate path segment (not
+ just the rightmost) will be created if it does not exist. This is
+ recursive.
+
+ """
+ head, tail = path.split(name)
+ if not tail:
+ head, tail = path.split(head)
+ if head and tail and not path.exists(head):
+ try:
+ makedirs(head, mode)
+ except OSError as e:
+ # be happy if someone already created the path
+ if e.errno != errno.EEXIST:
+ raise
+ if tail == curdir: # xxx/newdir/. exists if xxx/newdir exists
+ return
+ mkdir(name, mode)
+
+def removedirs(name):
+ """removedirs(path)
+
+ Super-rmdir; remove a leaf directory and all empty intermediate
+ ones. Works like rmdir except that, if the leaf directory is
+ successfully removed, directories corresponding to rightmost path
+ segments will be pruned away until either the whole path is
+ consumed or an error occurs. Errors during this latter phase are
+ ignored -- they generally mean that a directory was not empty.
+
+ """
+ rmdir(name)
+ head, tail = path.split(name)
+ if not tail:
+ head, tail = path.split(head)
+ while head and tail:
+ try:
+ rmdir(head)
+ except error:
+ break
+ head, tail = path.split(head)
+
+def renames(old, new):
+ """renames(old, new)
+
+ Super-rename; create directories as necessary and delete any left
+ empty. Works like rename, except creation of any intermediate
+ directories needed to make the new pathname good is attempted
+ first. After the rename, directories corresponding to rightmost
+ path segments of the old name will be pruned until either the
+ whole path is consumed or a nonempty directory is found.
+
+ Note: this function can fail with the new directory structure made
+ if you lack permissions needed to unlink the leaf directory or
+ file.
+
+ """
+ head, tail = path.split(new)
+ if head and tail and not path.exists(head):
+ makedirs(head)
+ rename(old, new)
+ head, tail = path.split(old)
+ if head and tail:
+ try:
+ removedirs(head)
+ except error:
+ pass
+
+__all__.extend(["makedirs", "removedirs", "renames"])
+
+def walk(top, topdown=True, onerror=None, followlinks=False):
+ """Directory tree generator.
+
+ For each directory in the directory tree rooted at top (including top
+ itself, but excluding '.' and '..'), yields a 3-tuple
+
+ dirpath, dirnames, filenames
+
+ dirpath is a string, the path to the directory. dirnames is a list of
+ the names of the subdirectories in dirpath (excluding '.' and '..').
+ filenames is a list of the names of the non-directory files in dirpath.
+ Note that the names in the lists are just names, with no path components.
+ To get a full path (which begins with top) to a file or directory in
+ dirpath, do os.path.join(dirpath, name).
+
+ If optional arg 'topdown' is true or not specified, the triple for a
+ directory is generated before the triples for any of its subdirectories
+ (directories are generated top down). If topdown is false, the triple
+ for a directory is generated after the triples for all of its
+ subdirectories (directories are generated bottom up).
+
+ When topdown is true, the caller can modify the dirnames list in-place
+ (e.g., via del or slice assignment), and walk will only recurse into the
+ subdirectories whose names remain in dirnames; this can be used to prune the
+ search, or to impose a specific order of visiting. Modifying dirnames when
+ topdown is false is ineffective, since the directories in dirnames have
+ already been generated by the time dirnames itself is generated. No matter
+ the value of topdown, the list of subdirectories is retrieved before the
+ tuples for the directory and its subdirectories are generated.
+
+ By default errors from the os.listdir() call are ignored. If
+ optional arg 'onerror' is specified, it should be a function; it
+ will be called with one argument, an os.error instance. It can
+ report the error to continue with the walk, or raise the exception
+ to abort the walk. Note that the filename is available as the
+ filename attribute of the exception object.
+
+ By default, os.walk does not follow symbolic links to subdirectories on
+ systems that support them. In order to get this functionality, set the
+ optional argument 'followlinks' to true.
+
+ Caution: if you pass a relative pathname for top, don't change the
+ current working directory between resumptions of walk. walk never
+ changes the current directory, and assumes that the client doesn't
+ either.
+
+ Example:
+
+ import os
+ from os.path import join, getsize
+ for root, dirs, files in os.walk('python/Lib/email'):
+ print root, "consumes",
+ print sum([getsize(join(root, name)) for name in files]),
+ print "bytes in", len(files), "non-directory files"
+ if 'CVS' in dirs:
+ dirs.remove('CVS') # don't visit CVS directories
+
+ """
+
+ islink, join, isdir = path.islink, path.join, path.isdir
+
+ # We may not have read permission for top, in which case we can't
+ # get a list of the files the directory contains. os.path.walk
+ # always suppressed the exception then, rather than blow up for a
+ # minor reason when (say) a thousand readable directories are still
+ # left to visit. That logic is copied here.
+ try:
+ # Note that listdir and error are globals in this module due
+ # to earlier import-*.
+ names = listdir(top)
+ except error as err:
+ if onerror is not None:
+ onerror(err)
+ return
+
+ dirs, nondirs = [], []
+ for name in names:
+ if isdir(join(top, name)):
+ dirs.append(name)
+ else:
+ nondirs.append(name)
+
+ if topdown:
+ yield top, dirs, nondirs
+ for name in dirs:
+ new_path = join(top, name)
+ if followlinks or not islink(new_path):
+ for x in walk(new_path, topdown, onerror, followlinks):
+ yield x
+ if not topdown:
+ yield top, dirs, nondirs
+
+__all__.append("walk")
+
+# Make sure os.environ exists, at least
+try:
+ environ
+except NameError:
+ environ = {}
+
+def execl(file, *args):
+ """execl(file, *args)
+
+ Execute the executable file with argument list args, replacing the
+ current process. """
+ execv(file, args)
+
+def execle(file, *args):
+ """execle(file, *args, env)
+
+ Execute the executable file with argument list args and
+ environment env, replacing the current process. """
+ env = args[-1]
+ execve(file, args[:-1], env)
+
+def execlp(file, *args):
+ """execlp(file, *args)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args, replacing the current process. """
+ execvp(file, args)
+
+def execlpe(file, *args):
+ """execlpe(file, *args, env)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args and environment env, replacing the current
+ process. """
+ env = args[-1]
+ execvpe(file, args[:-1], env)
+
+def execvp(file, args):
+ """execvp(file, args)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args, replacing the current process.
+ args may be a list or tuple of strings. """
+ _execvpe(file, args)
+
+def execvpe(file, args, env):
+ """execvpe(file, args, env)
+
+ Execute the executable file (which is searched for along $PATH)
+ with argument list args and environment env , replacing the
+ current process.
+ args may be a list or tuple of strings. """
+ _execvpe(file, args, env)
+
+__all__.extend(["execl","execle","execlp","execlpe","execvp","execvpe"])
+
+def _execvpe(file, args, env=None):
+ if env is not None:
+ func = execve
+ argrest = (args, env)
+ else:
+ func = execv
+ argrest = (args,)
+ env = environ
+
+ head, tail = path.split(file)
+ if head:
+ func(file, *argrest)
+ return
+ if 'PATH' in env:
+ envpath = env['PATH']
+ else:
+ envpath = defpath
+ PATH = envpath.split(pathsep)
+ saved_exc = None
+ saved_tb = None
+ for dir in PATH:
+ fullname = path.join(dir, file)
+ try:
+ func(fullname, *argrest)
+ except error as e:
+ tb = sys.exc_info()[2]
+ if (e.errno != errno.ENOENT and e.errno != errno.ENOTDIR
+ and saved_exc is None):
+ saved_exc = e
+ saved_tb = tb
+ if saved_exc:
+ raise error(saved_exc, saved_tb)
+ raise error(e, tb)
+
+# Change environ to automatically call putenv() if it exists
+try:
+ # This will fail if there's no putenv
+ putenv
+except NameError:
+ pass
+else:
+ import UserDict
+
+ # Fake unsetenv() for Windows
+ # not sure about os2 here but
+ # I'm guessing they are the same.
+
+ if name in ('os2', 'nt'):
+ def unsetenv(key):
+ putenv(key, "")
+
+ if name == "riscos":
+ # On RISC OS, all env access goes through getenv and putenv
+ from riscosenviron import _Environ
+ elif name in ('os2', 'nt'): # Where Env Var Names Must Be UPPERCASE
+ # But we store them as upper case
+ class _Environ(UserDict.IterableUserDict):
+ def __init__(self, environ):
+ UserDict.UserDict.__init__(self)
+ data = self.data
+ for k, v in environ.items():
+ data[k.upper()] = v
+ def __setitem__(self, key, item):
+ putenv(key, item)
+ self.data[key.upper()] = item
+ def __getitem__(self, key):
+ return self.data[key.upper()]
+ try:
+ unsetenv
+ except NameError:
+ def __delitem__(self, key):
+ del self.data[key.upper()]
+ else:
+ def __delitem__(self, key):
+ unsetenv(key)
+ del self.data[key.upper()]
+ def clear(self):
+ for key in self.data.keys():
+ unsetenv(key)
+ del self.data[key]
+ def pop(self, key, *args):
+ unsetenv(key)
+ return self.data.pop(key.upper(), *args)
+ def has_key(self, key):
+ return key.upper() in self.data
+ def __contains__(self, key):
+ return key.upper() in self.data
+ def get(self, key, failobj=None):
+ return self.data.get(key.upper(), failobj)
+ def update(self, dict=None, **kwargs):
+ if dict:
+ try:
+ keys = dict.keys()
+ except AttributeError:
+ # List of (key, value)
+ for k, v in dict:
+ self[k] = v
+ else:
+ # got keys
+ # cannot use items(), since mappings
+ # may not have them.
+ for k in keys:
+ self[k] = dict[k]
+ if kwargs:
+ self.update(kwargs)
+ def copy(self):
+ return dict(self)
+
+ else: # Where Env Var Names Can Be Mixed Case
+ class _Environ(UserDict.IterableUserDict):
+ def __init__(self, environ):
+ UserDict.UserDict.__init__(self)
+ self.data = environ
+ def __setitem__(self, key, item):
+ putenv(key, item)
+ self.data[key] = item
+ def update(self, dict=None, **kwargs):
+ if dict:
+ try:
+ keys = dict.keys()
+ except AttributeError:
+ # List of (key, value)
+ for k, v in dict:
+ self[k] = v
+ else:
+ # got keys
+ # cannot use items(), since mappings
+ # may not have them.
+ for k in keys:
+ self[k] = dict[k]
+ if kwargs:
+ self.update(kwargs)
+ try:
+ unsetenv
+ except NameError:
+ pass
+ else:
+ def __delitem__(self, key):
+ unsetenv(key)
+ del self.data[key]
+ def clear(self):
+ for key in self.data.keys():
+ unsetenv(key)
+ del self.data[key]
+ def pop(self, key, *args):
+ unsetenv(key)
+ return self.data.pop(key, *args)
+ def copy(self):
+ return dict(self)
+
+
+ environ = _Environ(environ)
+
+def getenv(key, default=None):
+ """Get an environment variable, return None if it doesn't exist.
+ The optional second argument can specify an alternate default."""
+ return environ.get(key, default)
+__all__.append("getenv")
+
+def _exists(name):
+ return name in globals()
+
+# Supply spawn*() (probably only for Unix)
+if _exists("fork") and not _exists("spawnv") and _exists("execv"):
+
+ P_WAIT = 0
+ P_NOWAIT = P_NOWAITO = 1
+
+ # XXX Should we support P_DETACH? I suppose it could fork()**2
+ # and close the std I/O streams. Also, P_OVERLAY is the same
+ # as execv*()?
+
+ def _spawnvef(mode, file, args, env, func):
+ # Internal helper; func is the exec*() function to use
+ pid = fork()
+ if not pid:
+ # Child
+ try:
+ if env is None:
+ func(file, args)
+ else:
+ func(file, args, env)
+ except:
+ _exit(127)
+ else:
+ # Parent
+ if mode == P_NOWAIT:
+ return pid # Caller is responsible for waiting!
+ while 1:
+ wpid, sts = waitpid(pid, 0)
+ if WIFSTOPPED(sts):
+ continue
+ elif WIFSIGNALED(sts):
+ return -WTERMSIG(sts)
+ elif WIFEXITED(sts):
+ return WEXITSTATUS(sts)
+ else:
+ raise error("Not stopped, signaled or exited???")
+
+ def spawnv(mode, file, args):
+ """spawnv(mode, file, args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, None, execv)
+
+ def spawnve(mode, file, args, env):
+ """spawnve(mode, file, args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+specified environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, env, execve)
+
+ # Note: spawnvp[e] is't currently supported on Windows
+
+ def spawnvp(mode, file, args):
+ """spawnvp(mode, file, args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, None, execvp)
+
+ def spawnvpe(mode, file, args, env):
+ """spawnvpe(mode, file, args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return _spawnvef(mode, file, args, env, execvpe)
+
+if _exists("spawnv"):
+ # These aren't supplied by the basic Windows code
+ # but can be easily implemented in Python
+
+ def spawnl(mode, file, *args):
+ """spawnl(mode, file, *args) -> integer
+
+Execute file with arguments from args in a subprocess.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return spawnv(mode, file, args)
+
+ def spawnle(mode, file, *args):
+ """spawnle(mode, file, *args, env) -> integer
+
+Execute file with arguments from args in a subprocess with the
+supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ env = args[-1]
+ return spawnve(mode, file, args[:-1], env)
+
+
+ __all__.extend(["spawnv", "spawnve", "spawnl", "spawnle",])
+
+
+if _exists("spawnvp"):
+ # At the moment, Windows doesn't implement spawnvp[e],
+ # so it won't have spawnlp[e] either.
+ def spawnlp(mode, file, *args):
+ """spawnlp(mode, file, *args) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ return spawnvp(mode, file, args)
+
+ def spawnlpe(mode, file, *args):
+ """spawnlpe(mode, file, *args, env) -> integer
+
+Execute file (which is looked for along $PATH) with arguments from
+args in a subprocess with the supplied environment.
+If mode == P_NOWAIT return the pid of the process.
+If mode == P_WAIT return the process's exit code if it exits normally;
+otherwise return -SIG, where SIG is the signal that killed it. """
+ env = args[-1]
+ return spawnvpe(mode, file, args[:-1], env)
+
+
+ __all__.extend(["spawnvp", "spawnvpe", "spawnlp", "spawnlpe",])
+
+
+# Supply popen2 etc. (for Unix)
+if _exists("fork"):
+ if not _exists("popen2"):
+ def popen2(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout) are returned."""
+ import warnings
+ msg = "os.popen2 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ close_fds=True)
+ return p.stdin, p.stdout
+ __all__.append("popen2")
+
+ if not _exists("popen3"):
+ def popen3(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout, child_stderr) are returned."""
+ import warnings
+ msg = "os.popen3 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ stderr=PIPE, close_fds=True)
+ return p.stdin, p.stdout, p.stderr
+ __all__.append("popen3")
+
+ if not _exists("popen4"):
+ def popen4(cmd, mode="t", bufsize=-1):
+ """Execute the shell command 'cmd' in a sub-process. On UNIX, 'cmd'
+ may be a sequence, in which case arguments will be passed directly to
+ the program without shell intervention (as with os.spawnv()). If 'cmd'
+ is a string it will be passed to the shell (as with os.system()). If
+ 'bufsize' is specified, it sets the buffer size for the I/O pipes. The
+ file objects (child_stdin, child_stdout_stderr) are returned."""
+ import warnings
+ msg = "os.popen4 is deprecated. Use the subprocess module."
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
+
+ import subprocess
+ PIPE = subprocess.PIPE
+ p = subprocess.Popen(cmd, shell=isinstance(cmd, basestring),
+ bufsize=bufsize, stdin=PIPE, stdout=PIPE,
+ stderr=subprocess.STDOUT, close_fds=True)
+ return p.stdin, p.stdout
+ __all__.append("popen4")
+
+#import copy_reg as _copy_reg
+
+def _make_stat_result(tup, dict):
+ return stat_result(tup, dict)
+
+def _pickle_stat_result(sr):
+ (type, args) = sr.__reduce__()
+ return (_make_stat_result, args)
+
+try:
+ _copy_reg.pickle(stat_result, _pickle_stat_result, _make_stat_result)
+except NameError: # stat_result may not exist
+ pass
+
+def _make_statvfs_result(tup, dict):
+ return statvfs_result(tup, dict)
+
+def _pickle_statvfs_result(sr):
+ (type, args) = sr.__reduce__()
+ return (_make_statvfs_result, args)
+
+try:
+ _copy_reg.pickle(statvfs_result, _pickle_statvfs_result,
+ _make_statvfs_result)
+except NameError: # statvfs_result may not exist
+ pass
+
+if not _exists("urandom"):
+ def urandom(n):
+ """urandom(n) -> str
+
+ Return a string of n random bytes suitable for cryptographic use.
+
+ """
+ if name != 'edk2':
+ try:
+ _urandomfd = open("/dev/urandom", O_RDONLY)
+ except (OSError, IOError):
+ raise NotImplementedError("/dev/urandom (or equivalent) not found")
+ try:
+ bs = b""
+ while n > len(bs):
+ bs += read(_urandomfd, n - len(bs))
+ finally:
+ close(_urandomfd)
+ else:
+ bs = b'/\xd3\x00\xa1\x11\x9b+\xef\x1dM-G\xd0\xa7\xd6v\x8f?o\xcaS\xd3aa\x03\xf8?b0b\xf2\xc3\xdek~\x19\xe0<\xbf\xe5! \xe23>\x04\x15\xa7u\x82\x0f\xf5~\xe0\xc3\xbe\x02\x17\x9a;\x90\xdaF\xa4\xb7\x9f\x05\x95}T^\x86b\x02b\xbe\xa8 ct\xbd\xd1>\tf\xe3\xf73\xeb\xae"\xdf\xea\xea\xa0I\xeb\xe2\xc6\xa5'
+ return bs[:n]
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/pydoc.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/pydoc.py
new file mode 100644
index 00000000..ec521ce7
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/pydoc.py
@@ -0,0 +1,2686 @@
+#!/usr/bin/env python3
+"""Generate Python documentation in HTML or text for interactive use.
+
+At the Python interactive prompt, calling help(thing) on a Python object
+documents the object, and calling help() starts up an interactive
+help session.
+
+Or, at the shell command line outside of Python:
+
+Run "pydoc <name>" to show documentation on something. <name> may be
+the name of a function, module, package, or a dotted reference to a
+class or function within a module or module in a package. If the
+argument contains a path segment delimiter (e.g. slash on Unix,
+backslash on Windows) it is treated as the path to a Python source file.
+
+Run "pydoc -k <keyword>" to search for a keyword in the synopsis lines
+of all available modules.
+
+Run "pydoc -p <port>" to start an HTTP server on the given port on the
+local machine. Port number 0 can be used to get an arbitrary unused port.
+
+Run "pydoc -b" to start an HTTP server on an arbitrary unused port and
+open a Web browser to interactively browse documentation. The -p option
+can be used with the -b option to explicitly specify the server port.
+
+Run "pydoc -w <name>" to write out the HTML documentation for a module
+to a file named "<name>.html".
+
+Module docs for core modules are assumed to be in
+
+ https://docs.python.org/X.Y/library/
+
+This can be overridden by setting the PYTHONDOCS environment variable
+to a different URL or to a local directory containing the Library
+Reference Manual pages.
+"""
+__all__ = ['help']
+__author__ = "Ka-Ping Yee <ping@lfw.org>"
+__date__ = "26 February 2001"
+
+__credits__ = """Guido van Rossum, for an excellent programming language.
+Tommy Burnette, the original creator of manpy.
+Paul Prescod, for all his work on onlinehelp.
+Richard Chamberlain, for the first implementation of textdoc.
+"""
+
+# Known bugs that can't be fixed here:
+# - synopsis() cannot be prevented from clobbering existing
+# loaded modules.
+# - If the __file__ attribute on a module is a relative path and
+# the current directory is changed with os.chdir(), an incorrect
+# path will be displayed.
+
+import builtins
+import importlib._bootstrap
+import importlib._bootstrap_external
+import importlib.machinery
+import importlib.util
+import inspect
+import io
+import os
+import pkgutil
+import platform
+import re
+import sys
+import time
+import tokenize
+import urllib.parse
+import warnings
+from collections import deque
+from reprlib import Repr
+from traceback import format_exception_only
+
+
+# --------------------------------------------------------- common routines
+
+def pathdirs():
+ """Convert sys.path into a list of absolute, existing, unique paths."""
+ dirs = []
+ normdirs = []
+ for dir in sys.path:
+ dir = os.path.abspath(dir or '.')
+ normdir = os.path.normcase(dir)
+ if normdir not in normdirs and os.path.isdir(dir):
+ dirs.append(dir)
+ normdirs.append(normdir)
+ return dirs
+
+def getdoc(object):
+ """Get the doc string or comments for an object."""
+ result = inspect.getdoc(object) or inspect.getcomments(object)
+ return result and re.sub('^ *\n', '', result.rstrip()) or ''
+
+def splitdoc(doc):
+ """Split a doc string into a synopsis line (if any) and the rest."""
+ lines = doc.strip().split('\n')
+ if len(lines) == 1:
+ return lines[0], ''
+ elif len(lines) >= 2 and not lines[1].rstrip():
+ return lines[0], '\n'.join(lines[2:])
+ return '', '\n'.join(lines)
+
+def classname(object, modname):
+ """Get a class name and qualify it with a module name if necessary."""
+ name = object.__name__
+ if object.__module__ != modname:
+ name = object.__module__ + '.' + name
+ return name
+
+def isdata(object):
+ """Check if an object is of a type that probably means it's data."""
+ return not (inspect.ismodule(object) or inspect.isclass(object) or
+ inspect.isroutine(object) or inspect.isframe(object) or
+ inspect.istraceback(object) or inspect.iscode(object))
+
+def replace(text, *pairs):
+ """Do a series of global replacements on a string."""
+ while pairs:
+ text = pairs[1].join(text.split(pairs[0]))
+ pairs = pairs[2:]
+ return text
+
+def cram(text, maxlen):
+ """Omit part of a string if needed to make it fit in a maximum length."""
+ if len(text) > maxlen:
+ pre = max(0, (maxlen-3)//2)
+ post = max(0, maxlen-3-pre)
+ return text[:pre] + '...' + text[len(text)-post:]
+ return text
+
+_re_stripid = re.compile(r' at 0x[0-9a-f]{6,16}(>+)$', re.IGNORECASE)
+def stripid(text):
+ """Remove the hexadecimal id from a Python object representation."""
+ # The behaviour of %p is implementation-dependent in terms of case.
+ return _re_stripid.sub(r'\1', text)
+
+def _is_some_method(obj):
+ return (inspect.isfunction(obj) or
+ inspect.ismethod(obj) or
+ inspect.isbuiltin(obj) or
+ inspect.ismethoddescriptor(obj))
+
+def _is_bound_method(fn):
+ """
+ Returns True if fn is a bound method, regardless of whether
+ fn was implemented in Python or in C.
+ """
+ if inspect.ismethod(fn):
+ return True
+ if inspect.isbuiltin(fn):
+ self = getattr(fn, '__self__', None)
+ return not (inspect.ismodule(self) or (self is None))
+ return False
+
+
+def allmethods(cl):
+ methods = {}
+ for key, value in inspect.getmembers(cl, _is_some_method):
+ methods[key] = 1
+ for base in cl.__bases__:
+ methods.update(allmethods(base)) # all your base are belong to us
+ for key in methods.keys():
+ methods[key] = getattr(cl, key)
+ return methods
+
+def _split_list(s, predicate):
+ """Split sequence s via predicate, and return pair ([true], [false]).
+
+ The return value is a 2-tuple of lists,
+ ([x for x in s if predicate(x)],
+ [x for x in s if not predicate(x)])
+ """
+
+ yes = []
+ no = []
+ for x in s:
+ if predicate(x):
+ yes.append(x)
+ else:
+ no.append(x)
+ return yes, no
+
+def visiblename(name, all=None, obj=None):
+ """Decide whether to show documentation on a variable."""
+ # Certain special names are redundant or internal.
+ # XXX Remove __initializing__?
+ if name in {'__author__', '__builtins__', '__cached__', '__credits__',
+ '__date__', '__doc__', '__file__', '__spec__',
+ '__loader__', '__module__', '__name__', '__package__',
+ '__path__', '__qualname__', '__slots__', '__version__'}:
+ return 0
+ # Private names are hidden, but special names are displayed.
+ if name.startswith('__') and name.endswith('__'): return 1
+ # Namedtuples have public fields and methods with a single leading underscore
+ if name.startswith('_') and hasattr(obj, '_fields'):
+ return True
+ if all is not None:
+ # only document that which the programmer exported in __all__
+ return name in all
+ else:
+ return not name.startswith('_')
+
+def classify_class_attrs(object):
+ """Wrap inspect.classify_class_attrs, with fixup for data descriptors."""
+ results = []
+ for (name, kind, cls, value) in inspect.classify_class_attrs(object):
+ if inspect.isdatadescriptor(value):
+ kind = 'data descriptor'
+ results.append((name, kind, cls, value))
+ return results
+
+def sort_attributes(attrs, object):
+ 'Sort the attrs list in-place by _fields and then alphabetically by name'
+ # This allows data descriptors to be ordered according
+ # to a _fields attribute if present.
+ fields = getattr(object, '_fields', [])
+ try:
+ field_order = {name : i-len(fields) for (i, name) in enumerate(fields)}
+ except TypeError:
+ field_order = {}
+ keyfunc = lambda attr: (field_order.get(attr[0], 0), attr[0])
+ attrs.sort(key=keyfunc)
+
+# ----------------------------------------------------- module manipulation
+
+def ispackage(path):
+ """Guess whether a path refers to a package directory."""
+ if os.path.isdir(path):
+ for ext in ('.py', '.pyc'):
+ if os.path.isfile(os.path.join(path, '__init__' + ext)):
+ return True
+ return False
+
+def source_synopsis(file):
+ line = file.readline()
+ while line[:1] == '#' or not line.strip():
+ line = file.readline()
+ if not line: break
+ line = line.strip()
+ if line[:4] == 'r"""': line = line[1:]
+ if line[:3] == '"""':
+ line = line[3:]
+ if line[-1:] == '\\': line = line[:-1]
+ while not line.strip():
+ line = file.readline()
+ if not line: break
+ result = line.split('"""')[0].strip()
+ else: result = None
+ return result
+
+def synopsis(filename, cache={}):
+ """Get the one-line summary out of a module file."""
+ mtime = os.stat(filename).st_mtime
+ lastupdate, result = cache.get(filename, (None, None))
+ if lastupdate is None or lastupdate < mtime:
+ # Look for binary suffixes first, falling back to source.
+ if filename.endswith(tuple(importlib.machinery.BYTECODE_SUFFIXES)):
+ loader_cls = importlib.machinery.SourcelessFileLoader
+ elif filename.endswith(tuple(importlib.machinery.EXTENSION_SUFFIXES)):
+ loader_cls = importlib.machinery.ExtensionFileLoader
+ else:
+ loader_cls = None
+ # Now handle the choice.
+ if loader_cls is None:
+ # Must be a source file.
+ try:
+ file = tokenize.open(filename)
+ except OSError:
+ # module can't be opened, so skip it
+ return None
+ # text modules can be directly examined
+ with file:
+ result = source_synopsis(file)
+ else:
+ # Must be a binary module, which has to be imported.
+ loader = loader_cls('__temp__', filename)
+ # XXX We probably don't need to pass in the loader here.
+ spec = importlib.util.spec_from_file_location('__temp__', filename,
+ loader=loader)
+ try:
+ module = importlib._bootstrap._load(spec)
+ except:
+ return None
+ del sys.modules['__temp__']
+ result = module.__doc__.splitlines()[0] if module.__doc__ else None
+ # Cache the result.
+ cache[filename] = (mtime, result)
+ return result
+
+class ErrorDuringImport(Exception):
+ """Errors that occurred while trying to import something to document it."""
+ def __init__(self, filename, exc_info):
+ self.filename = filename
+ self.exc, self.value, self.tb = exc_info
+
+ def __str__(self):
+ exc = self.exc.__name__
+ return 'problem in %s - %s: %s' % (self.filename, exc, self.value)
+
+def importfile(path):
+ """Import a Python source file or compiled file given its path."""
+ magic = importlib.util.MAGIC_NUMBER
+ with open(path, 'rb') as file:
+ is_bytecode = magic == file.read(len(magic))
+ filename = os.path.basename(path)
+ name, ext = os.path.splitext(filename)
+ if is_bytecode:
+ loader = importlib._bootstrap_external.SourcelessFileLoader(name, path)
+ else:
+ loader = importlib._bootstrap_external.SourceFileLoader(name, path)
+ # XXX We probably don't need to pass in the loader here.
+ spec = importlib.util.spec_from_file_location(name, path, loader=loader)
+ try:
+ return importlib._bootstrap._load(spec)
+ except:
+ raise ErrorDuringImport(path, sys.exc_info())
+
+def safeimport(path, forceload=0, cache={}):
+ """Import a module; handle errors; return None if the module isn't found.
+
+ If the module *is* found but an exception occurs, it's wrapped in an
+ ErrorDuringImport exception and reraised. Unlike __import__, if a
+ package path is specified, the module at the end of the path is returned,
+ not the package at the beginning. If the optional 'forceload' argument
+ is 1, we reload the module from disk (unless it's a dynamic extension)."""
+ try:
+ # If forceload is 1 and the module has been previously loaded from
+ # disk, we always have to reload the module. Checking the file's
+ # mtime isn't good enough (e.g. the module could contain a class
+ # that inherits from another module that has changed).
+ if forceload and path in sys.modules:
+ if path not in sys.builtin_module_names:
+ # Remove the module from sys.modules and re-import to try
+ # and avoid problems with partially loaded modules.
+ # Also remove any submodules because they won't appear
+ # in the newly loaded module's namespace if they're already
+ # in sys.modules.
+ subs = [m for m in sys.modules if m.startswith(path + '.')]
+ for key in [path] + subs:
+ # Prevent garbage collection.
+ cache[key] = sys.modules[key]
+ del sys.modules[key]
+ module = __import__(path)
+ except:
+ # Did the error occur before or after the module was found?
+ (exc, value, tb) = info = sys.exc_info()
+ if path in sys.modules:
+ # An error occurred while executing the imported module.
+ raise ErrorDuringImport(sys.modules[path].__file__, info)
+ elif exc is SyntaxError:
+ # A SyntaxError occurred before we could execute the module.
+ raise ErrorDuringImport(value.filename, info)
+ elif issubclass(exc, ImportError) and value.name == path:
+ # No such module in the path.
+ return None
+ else:
+ # Some other error occurred during the importing process.
+ raise ErrorDuringImport(path, sys.exc_info())
+ for part in path.split('.')[1:]:
+ try: module = getattr(module, part)
+ except AttributeError: return None
+ return module
+
+# ---------------------------------------------------- formatter base class
+
+class Doc:
+
+ PYTHONDOCS = os.environ.get("PYTHONDOCS",
+ "https://docs.python.org/%d.%d/library"
+ % sys.version_info[:2])
+
+ def document(self, object, name=None, *args):
+ """Generate documentation for an object."""
+ args = (object, name) + args
+ # 'try' clause is to attempt to handle the possibility that inspect
+ # identifies something in a way that pydoc itself has issues handling;
+ # think 'super' and how it is a descriptor (which raises the exception
+ # by lacking a __name__ attribute) and an instance.
+ if inspect.isgetsetdescriptor(object): return self.docdata(*args)
+ if inspect.ismemberdescriptor(object): return self.docdata(*args)
+ try:
+ if inspect.ismodule(object): return self.docmodule(*args)
+ if inspect.isclass(object): return self.docclass(*args)
+ if inspect.isroutine(object): return self.docroutine(*args)
+ except AttributeError:
+ pass
+ if isinstance(object, property): return self.docproperty(*args)
+ return self.docother(*args)
+
+ def fail(self, object, name=None, *args):
+ """Raise an exception for unimplemented types."""
+ message = "don't know how to document object%s of type %s" % (
+ name and ' ' + repr(name), type(object).__name__)
+ raise TypeError(message)
+
+ docmodule = docclass = docroutine = docother = docproperty = docdata = fail
+
+ def getdocloc(self, object,
+ basedir=os.path.join(sys.base_exec_prefix, "lib",
+ "python%d.%d" % sys.version_info[:2])):
+ """Return the location of module docs or None"""
+
+ try:
+ file = inspect.getabsfile(object)
+ except TypeError:
+ file = '(built-in)'
+
+ docloc = os.environ.get("PYTHONDOCS", self.PYTHONDOCS)
+
+ basedir = os.path.normcase(basedir)
+ if (isinstance(object, type(os)) and
+ (object.__name__ in ('errno', 'exceptions', 'gc', 'imp',
+ 'marshal', 'posix', 'signal', 'sys',
+ '_thread', 'zipimport') or
+ (file.startswith(basedir) and
+ not file.startswith(os.path.join(basedir, 'site-packages')))) and
+ object.__name__ not in ('xml.etree', 'test.pydoc_mod')):
+ if docloc.startswith(("http://", "https://")):
+ docloc = "%s/%s" % (docloc.rstrip("/"), object.__name__.lower())
+ else:
+ docloc = os.path.join(docloc, object.__name__.lower() + ".html")
+ else:
+ docloc = None
+ return docloc
+
+# -------------------------------------------- HTML documentation generator
+
+class HTMLRepr(Repr):
+ """Class for safely making an HTML representation of a Python object."""
+ def __init__(self):
+ Repr.__init__(self)
+ self.maxlist = self.maxtuple = 20
+ self.maxdict = 10
+ self.maxstring = self.maxother = 100
+
+ def escape(self, text):
+ return replace(text, '&', '&amp;', '<', '&lt;', '>', '&gt;')
+
+ def repr(self, object):
+ return Repr.repr(self, object)
+
+ def repr1(self, x, level):
+ if hasattr(type(x), '__name__'):
+ methodname = 'repr_' + '_'.join(type(x).__name__.split())
+ if hasattr(self, methodname):
+ return getattr(self, methodname)(x, level)
+ return self.escape(cram(stripid(repr(x)), self.maxother))
+
+ def repr_string(self, x, level):
+ test = cram(x, self.maxstring)
+ testrepr = repr(test)
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+ # Backslashes are only literal in the string and are never
+ # needed to make any special characters, so show a raw string.
+ return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
+ return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
+ r'<font color="#c040c0">\1</font>',
+ self.escape(testrepr))
+
+ repr_str = repr_string
+
+ def repr_instance(self, x, level):
+ try:
+ return self.escape(cram(stripid(repr(x)), self.maxstring))
+ except:
+ return self.escape('<%s instance>' % x.__class__.__name__)
+
+ repr_unicode = repr_string
+
+class HTMLDoc(Doc):
+ """Formatter class for HTML documentation."""
+
+ # ------------------------------------------- HTML formatting utilities
+
+ _repr_instance = HTMLRepr()
+ repr = _repr_instance.repr
+ escape = _repr_instance.escape
+
+ def page(self, title, contents):
+ """Format an HTML page."""
+ return '''\
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: %s</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head><body bgcolor="#f0f0f8">
+%s
+</body></html>''' % (title, contents)
+
+ def heading(self, title, fgcol, bgcol, extras=''):
+ """Format a page heading."""
+ return '''
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="%s">
+<td valign=bottom>&nbsp;<br>
+<font color="%s" face="helvetica, arial">&nbsp;<br>%s</font></td
+><td align=right valign=bottom
+><font color="%s" face="helvetica, arial">%s</font></td></tr></table>
+ ''' % (bgcol, fgcol, title, fgcol, extras or '&nbsp;')
+
+ def section(self, title, fgcol, bgcol, contents, width=6,
+ prelude='', marginalia=None, gap='&nbsp;'):
+ """Format a section with a heading."""
+ if marginalia is None:
+ marginalia = '<tt>' + '&nbsp;' * width + '</tt>'
+ result = '''<p>
+<table width="100%%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="%s">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="%s" face="helvetica, arial">%s</font></td></tr>
+ ''' % (bgcol, fgcol, title)
+ if prelude:
+ result = result + '''
+<tr bgcolor="%s"><td rowspan=2>%s</td>
+<td colspan=2>%s</td></tr>
+<tr><td>%s</td>''' % (bgcol, marginalia, prelude, gap)
+ else:
+ result = result + '''
+<tr><td bgcolor="%s">%s</td><td>%s</td>''' % (bgcol, marginalia, gap)
+
+ return result + '\n<td width="100%%">%s</td></tr></table>' % contents
+
+ def bigsection(self, title, *args):
+ """Format a section with a big heading."""
+ title = '<big><strong>%s</strong></big>' % title
+ return self.section(title, *args)
+
+ def preformat(self, text):
+ """Format literal preformatted text."""
+ text = self.escape(text.expandtabs())
+ return replace(text, '\n\n', '\n \n', '\n\n', '\n \n',
+ ' ', '&nbsp;', '\n', '<br>\n')
+
+ def multicolumn(self, list, format, cols=4):
+ """Format a list of items into a multi-column list."""
+ result = ''
+ rows = (len(list)+cols-1)//cols
+ for col in range(cols):
+ result = result + '<td width="%d%%" valign=top>' % (100//cols)
+ for i in range(rows*col, rows*col+rows):
+ if i < len(list):
+ result = result + format(list[i]) + '<br>\n'
+ result = result + '</td>'
+ return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
+
+ def grey(self, text): return '<font color="#909090">%s</font>' % text
+
+ def namelink(self, name, *dicts):
+ """Make a link for an identifier, given name-to-URL mappings."""
+ for dict in dicts:
+ if name in dict:
+ return '<a href="%s">%s</a>' % (dict[name], name)
+ return name
+
+ def classlink(self, object, modname):
+ """Make a link for a class."""
+ name, module = object.__name__, sys.modules.get(object.__module__)
+ if hasattr(module, name) and getattr(module, name) is object:
+ return '<a href="%s.html#%s">%s</a>' % (
+ module.__name__, name, classname(object, modname))
+ return classname(object, modname)
+
+ def modulelink(self, object):
+ """Make a link for a module."""
+ return '<a href="%s.html">%s</a>' % (object.__name__, object.__name__)
+
+ def modpkglink(self, modpkginfo):
+ """Make a link for a module or package to display in an index."""
+ name, path, ispackage, shadowed = modpkginfo
+ if shadowed:
+ return self.grey(name)
+ if path:
+ url = '%s.%s.html' % (path, name)
+ else:
+ url = '%s.html' % name
+ if ispackage:
+ text = '<strong>%s</strong>&nbsp;(package)' % name
+ else:
+ text = name
+ return '<a href="%s">%s</a>' % (url, text)
+
+ def filelink(self, url, path):
+ """Make a link to source file."""
+ return '<a href="file:%s">%s</a>' % (url, path)
+
+ def markup(self, text, escape=None, funcs={}, classes={}, methods={}):
+ """Mark up some plain text, given a context of symbols to look for.
+ Each context dictionary maps object names to anchor names."""
+ escape = escape or self.escape
+ results = []
+ here = 0
+ pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
+ r'RFC[- ]?(\d+)|'
+ r'PEP[- ]?(\d+)|'
+ r'(self\.)?(\w+))')
+ while True:
+ match = pattern.search(text, here)
+ if not match: break
+ start, end = match.span()
+ results.append(escape(text[here:start]))
+
+ all, scheme, rfc, pep, selfdot, name = match.groups()
+ if scheme:
+ url = escape(all).replace('"', '&quot;')
+ results.append('<a href="%s">%s</a>' % (url, url))
+ elif rfc:
+ url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))
+ elif pep:
+ url = 'http://www.python.org/dev/peps/pep-%04d/' % int(pep)
+ results.append('<a href="%s">%s</a>' % (url, escape(all)))
+ elif selfdot:
+ # Create a link for methods like 'self.method(...)'
+ # and use <strong> for attributes like 'self.attr'
+ if text[end:end+1] == '(':
+ results.append('self.' + self.namelink(name, methods))
+ else:
+ results.append('self.<strong>%s</strong>' % name)
+ elif text[end:end+1] == '(':
+ results.append(self.namelink(name, methods, funcs, classes))
+ else:
+ results.append(self.namelink(name, classes))
+ here = end
+ results.append(escape(text[here:]))
+ return ''.join(results)
+
+ # ---------------------------------------------- type-specific routines
+
+ def formattree(self, tree, modname, parent=None):
+ """Produce HTML for a class tree as given by inspect.getclasstree()."""
+ result = ''
+ for entry in tree:
+ if type(entry) is type(()):
+ c, bases = entry
+ result = result + '<dt><font face="helvetica, arial">'
+ result = result + self.classlink(c, modname)
+ if bases and bases != (parent,):
+ parents = []
+ for base in bases:
+ parents.append(self.classlink(base, modname))
+ result = result + '(' + ', '.join(parents) + ')'
+ result = result + '\n</font></dt>'
+ elif type(entry) is type([]):
+ result = result + '<dd>\n%s</dd>\n' % self.formattree(
+ entry, modname, c)
+ return '<dl>\n%s</dl>\n' % result
+
+ def docmodule(self, object, name=None, mod=None, *ignored):
+ """Produce HTML documentation for a module object."""
+ name = object.__name__ # ignore the passed-in name
+ try:
+ all = object.__all__
+ except AttributeError:
+ all = None
+ parts = name.split('.')
+ links = []
+ for i in range(len(parts)-1):
+ links.append(
+ '<a href="%s.html"><font color="#ffffff">%s</font></a>' %
+ ('.'.join(parts[:i+1]), parts[i]))
+ linkedname = '.'.join(links + parts[-1:])
+ head = '<big><big><strong>%s</strong></big></big>' % linkedname
+ try:
+ path = inspect.getabsfile(object)
+ url = urllib.parse.quote(path)
+ filelink = self.filelink(url, path)
+ except TypeError:
+ filelink = '(built-in)'
+ info = []
+ if hasattr(object, '__version__'):
+ version = str(object.__version__)
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+ version = version[11:-1].strip()
+ info.append('version %s' % self.escape(version))
+ if hasattr(object, '__date__'):
+ info.append(self.escape(str(object.__date__)))
+ if info:
+ head = head + ' (%s)' % ', '.join(info)
+ docloc = self.getdocloc(object)
+ if docloc is not None:
+ docloc = '<br><a href="%(docloc)s">Module Reference</a>' % locals()
+ else:
+ docloc = ''
+ result = self.heading(
+ head, '#ffffff', '#7799ee',
+ '<a href=".">index</a><br>' + filelink + docloc)
+
+ modules = inspect.getmembers(object, inspect.ismodule)
+
+ classes, cdict = [], {}
+ for key, value in inspect.getmembers(object, inspect.isclass):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ (inspect.getmodule(value) or object) is object):
+ if visiblename(key, all, object):
+ classes.append((key, value))
+ cdict[key] = cdict[value] = '#' + key
+ for key, value in classes:
+ for base in value.__bases__:
+ key, modname = base.__name__, base.__module__
+ module = sys.modules.get(modname)
+ if modname != name and module and hasattr(module, key):
+ if getattr(module, key) is base:
+ if not key in cdict:
+ cdict[key] = cdict[base] = modname + '.html#' + key
+ funcs, fdict = [], {}
+ for key, value in inspect.getmembers(object, inspect.isroutine):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+ if visiblename(key, all, object):
+ funcs.append((key, value))
+ fdict[key] = '#-' + key
+ if inspect.isfunction(value): fdict[value] = fdict[key]
+ data = []
+ for key, value in inspect.getmembers(object, isdata):
+ if visiblename(key, all, object):
+ data.append((key, value))
+
+ doc = self.markup(getdoc(object), self.preformat, fdict, cdict)
+ doc = doc and '<tt>%s</tt>' % doc
+ result = result + '<p>%s</p>\n' % doc
+
+ if hasattr(object, '__path__'):
+ modpkgs = []
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+ modpkgs.append((modname, name, ispkg, 0))
+ modpkgs.sort()
+ contents = self.multicolumn(modpkgs, self.modpkglink)
+ result = result + self.bigsection(
+ 'Package Contents', '#ffffff', '#aa55cc', contents)
+ elif modules:
+ contents = self.multicolumn(
+ modules, lambda t: self.modulelink(t[1]))
+ result = result + self.bigsection(
+ 'Modules', '#ffffff', '#aa55cc', contents)
+
+ if classes:
+ classlist = [value for (key, value) in classes]
+ contents = [
+ self.formattree(inspect.getclasstree(classlist, 1), name)]
+ for key, value in classes:
+ contents.append(self.document(value, key, name, fdict, cdict))
+ result = result + self.bigsection(
+ 'Classes', '#ffffff', '#ee77aa', ' '.join(contents))
+ if funcs:
+ contents = []
+ for key, value in funcs:
+ contents.append(self.document(value, key, name, fdict, cdict))
+ result = result + self.bigsection(
+ 'Functions', '#ffffff', '#eeaa77', ' '.join(contents))
+ if data:
+ contents = []
+ for key, value in data:
+ contents.append(self.document(value, key))
+ result = result + self.bigsection(
+ 'Data', '#ffffff', '#55aa55', '<br>\n'.join(contents))
+ if hasattr(object, '__author__'):
+ contents = self.markup(str(object.__author__), self.preformat)
+ result = result + self.bigsection(
+ 'Author', '#ffffff', '#7799ee', contents)
+ if hasattr(object, '__credits__'):
+ contents = self.markup(str(object.__credits__), self.preformat)
+ result = result + self.bigsection(
+ 'Credits', '#ffffff', '#7799ee', contents)
+
+ return result
+
+ def docclass(self, object, name=None, mod=None, funcs={}, classes={},
+ *ignored):
+ """Produce HTML documentation for a class object."""
+ realname = object.__name__
+ name = name or realname
+ bases = object.__bases__
+
+ contents = []
+ push = contents.append
+
+ # Cute little class to pump out a horizontal rule between sections.
+ class HorizontalRule:
+ def __init__(self):
+ self.needone = 0
+ def maybe(self):
+ if self.needone:
+ push('<hr>\n')
+ self.needone = 1
+ hr = HorizontalRule()
+
+ # List the mro, if non-trivial.
+ mro = deque(inspect.getmro(object))
+ if len(mro) > 2:
+ hr.maybe()
+ push('<dl><dt>Method resolution order:</dt>\n')
+ for base in mro:
+ push('<dd>%s</dd>\n' % self.classlink(base,
+ object.__module__))
+ push('</dl>\n')
+
+ def spill(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ push(self._docdescriptor(name, value, mod))
+ else:
+ push(self.document(value, name, mod,
+ funcs, classes, mdict, object))
+ push('\n')
+ return attrs
+
+ def spilldescriptors(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push(self._docdescriptor(name, value, mod))
+ return attrs
+
+ def spilldata(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ base = self.docother(getattr(object, name), name, mod)
+ if callable(value) or inspect.isdatadescriptor(value):
+ doc = getattr(value, "__doc__", None)
+ else:
+ doc = None
+ if doc is None:
+ push('<dl><dt>%s</dl>\n' % base)
+ else:
+ doc = self.markup(getdoc(value), self.preformat,
+ funcs, classes, mdict)
+ doc = '<dd><tt>%s</tt>' % doc
+ push('<dl><dt>%s%s</dl>\n' % (base, doc))
+ push('\n')
+ return attrs
+
+ attrs = [(name, kind, cls, value)
+ for name, kind, cls, value in classify_class_attrs(object)
+ if visiblename(name, obj=object)]
+
+ mdict = {}
+ for key, kind, homecls, value in attrs:
+ mdict[key] = anchor = '#' + name + '-' + key
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ pass
+ try:
+ # The value may not be hashable (e.g., a data attr with
+ # a dict or list value).
+ mdict[value] = anchor
+ except TypeError:
+ pass
+
+ while attrs:
+ if mro:
+ thisclass = mro.popleft()
+ else:
+ thisclass = attrs[0][2]
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+ if thisclass is builtins.object:
+ attrs = inherited
+ continue
+ elif thisclass is object:
+ tag = 'defined here'
+ else:
+ tag = 'inherited from %s' % self.classlink(thisclass,
+ object.__module__)
+ tag += ':<br>\n'
+
+ sort_attributes(attrs, object)
+
+ # Pump out the attrs, segregated by kind.
+ attrs = spill('Methods %s' % tag, attrs,
+ lambda t: t[1] == 'method')
+ attrs = spill('Class methods %s' % tag, attrs,
+ lambda t: t[1] == 'class method')
+ attrs = spill('Static methods %s' % tag, attrs,
+ lambda t: t[1] == 'static method')
+ attrs = spilldescriptors('Data descriptors %s' % tag, attrs,
+ lambda t: t[1] == 'data descriptor')
+ attrs = spilldata('Data and other attributes %s' % tag, attrs,
+ lambda t: t[1] == 'data')
+ assert attrs == []
+ attrs = inherited
+
+ contents = ''.join(contents)
+
+ if name == realname:
+ title = '<a name="%s">class <strong>%s</strong></a>' % (
+ name, realname)
+ else:
+ title = '<strong>%s</strong> = <a name="%s">class %s</a>' % (
+ name, name, realname)
+ if bases:
+ parents = []
+ for base in bases:
+ parents.append(self.classlink(base, object.__module__))
+ title = title + '(%s)' % ', '.join(parents)
+ doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict)
+ doc = doc and '<tt>%s<br>&nbsp;</tt>' % doc
+
+ return self.section(title, '#000000', '#ffc8d8', contents, 3, doc)
+
+ def formatvalue(self, object):
+ """Format an argument default value as text."""
+ return self.grey('=' + self.repr(object))
+
+ def docroutine(self, object, name=None, mod=None,
+ funcs={}, classes={}, methods={}, cl=None):
+ """Produce HTML documentation for a function or method object."""
+ realname = object.__name__
+ name = name or realname
+ anchor = (cl and cl.__name__ or '') + '-' + name
+ note = ''
+ skipdocs = 0
+ if _is_bound_method(object):
+ imclass = object.__self__.__class__
+ if cl:
+ if imclass is not cl:
+ note = ' from ' + self.classlink(imclass, mod)
+ else:
+ if object.__self__ is not None:
+ note = ' method of %s instance' % self.classlink(
+ object.__self__.__class__, mod)
+ else:
+ note = ' unbound %s method' % self.classlink(imclass,mod)
+
+ if name == realname:
+ title = '<a name="%s"><strong>%s</strong></a>' % (anchor, realname)
+ else:
+ if cl and inspect.getattr_static(cl, realname, []) is object:
+ reallink = '<a href="#%s">%s</a>' % (
+ cl.__name__ + '-' + realname, realname)
+ skipdocs = 1
+ else:
+ reallink = realname
+ title = '<a name="%s"><strong>%s</strong></a> = %s' % (
+ anchor, name, reallink)
+ argspec = None
+ if inspect.isroutine(object):
+ try:
+ signature = inspect.signature(object)
+ except (ValueError, TypeError):
+ signature = None
+ if signature:
+ argspec = str(signature)
+ if realname == '<lambda>':
+ title = '<strong>%s</strong> <em>lambda</em> ' % name
+ # XXX lambda's won't usually have func_annotations['return']
+ # since the syntax doesn't support but it is possible.
+ # So removing parentheses isn't truly safe.
+ argspec = argspec[1:-1] # remove parentheses
+ if not argspec:
+ argspec = '(...)'
+
+ decl = title + self.escape(argspec) + (note and self.grey(
+ '<font face="helvetica, arial">%s</font>' % note))
+
+ if skipdocs:
+ return '<dl><dt>%s</dt></dl>\n' % decl
+ else:
+ doc = self.markup(
+ getdoc(object), self.preformat, funcs, classes, methods)
+ doc = doc and '<dd><tt>%s</tt></dd>' % doc
+ return '<dl><dt>%s</dt>%s</dl>\n' % (decl, doc)
+
+ def _docdescriptor(self, name, value, mod):
+ results = []
+ push = results.append
+
+ if name:
+ push('<dl><dt><strong>%s</strong></dt>\n' % name)
+ if value.__doc__ is not None:
+ doc = self.markup(getdoc(value), self.preformat)
+ push('<dd><tt>%s</tt></dd>\n' % doc)
+ push('</dl>\n')
+
+ return ''.join(results)
+
+ def docproperty(self, object, name=None, mod=None, cl=None):
+ """Produce html documentation for a property."""
+ return self._docdescriptor(name, object, mod)
+
+ def docother(self, object, name=None, mod=None, *ignored):
+ """Produce HTML documentation for a data object."""
+ lhs = name and '<strong>%s</strong> = ' % name or ''
+ return lhs + self.repr(object)
+
+ def docdata(self, object, name=None, mod=None, cl=None):
+ """Produce html documentation for a data descriptor."""
+ return self._docdescriptor(name, object, mod)
+
+ def index(self, dir, shadowed=None):
+ """Generate an HTML index for a directory of modules."""
+ modpkgs = []
+ if shadowed is None: shadowed = {}
+ for importer, name, ispkg in pkgutil.iter_modules([dir]):
+ if any((0xD800 <= ord(ch) <= 0xDFFF) for ch in name):
+ # ignore a module if its name contains a surrogate character
+ continue
+ modpkgs.append((name, '', ispkg, name in shadowed))
+ shadowed[name] = 1
+
+ modpkgs.sort()
+ contents = self.multicolumn(modpkgs, self.modpkglink)
+ return self.bigsection(dir, '#ffffff', '#ee77aa', contents)
+
+# -------------------------------------------- text documentation generator
+
+class TextRepr(Repr):
+ """Class for safely making a text representation of a Python object."""
+ def __init__(self):
+ Repr.__init__(self)
+ self.maxlist = self.maxtuple = 20
+ self.maxdict = 10
+ self.maxstring = self.maxother = 100
+
+ def repr1(self, x, level):
+ if hasattr(type(x), '__name__'):
+ methodname = 'repr_' + '_'.join(type(x).__name__.split())
+ if hasattr(self, methodname):
+ return getattr(self, methodname)(x, level)
+ return cram(stripid(repr(x)), self.maxother)
+
+ def repr_string(self, x, level):
+ test = cram(x, self.maxstring)
+ testrepr = repr(test)
+ if '\\' in test and '\\' not in replace(testrepr, r'\\', ''):
+ # Backslashes are only literal in the string and are never
+ # needed to make any special characters, so show a raw string.
+ return 'r' + testrepr[0] + test + testrepr[0]
+ return testrepr
+
+ repr_str = repr_string
+
+ def repr_instance(self, x, level):
+ try:
+ return cram(stripid(repr(x)), self.maxstring)
+ except:
+ return '<%s instance>' % x.__class__.__name__
+
+class TextDoc(Doc):
+ """Formatter class for text documentation."""
+
+ # ------------------------------------------- text formatting utilities
+
+ _repr_instance = TextRepr()
+ repr = _repr_instance.repr
+
+ def bold(self, text):
+ """Format a string in bold by overstriking."""
+ return ''.join(ch + '\b' + ch for ch in text)
+
+ def indent(self, text, prefix=' '):
+ """Indent text by prepending a given prefix to each line."""
+ if not text: return ''
+ lines = [prefix + line for line in text.split('\n')]
+ if lines: lines[-1] = lines[-1].rstrip()
+ return '\n'.join(lines)
+
+ def section(self, title, contents):
+ """Format a section with a given heading."""
+ clean_contents = self.indent(contents).rstrip()
+ return self.bold(title) + '\n' + clean_contents + '\n\n'
+
+ # ---------------------------------------------- type-specific routines
+
+ def formattree(self, tree, modname, parent=None, prefix=''):
+ """Render in text a class tree as returned by inspect.getclasstree()."""
+ result = ''
+ for entry in tree:
+ if type(entry) is type(()):
+ c, bases = entry
+ result = result + prefix + classname(c, modname)
+ if bases and bases != (parent,):
+ parents = (classname(c, modname) for c in bases)
+ result = result + '(%s)' % ', '.join(parents)
+ result = result + '\n'
+ elif type(entry) is type([]):
+ result = result + self.formattree(
+ entry, modname, c, prefix + ' ')
+ return result
+
+ def docmodule(self, object, name=None, mod=None):
+ """Produce text documentation for a given module object."""
+ name = object.__name__ # ignore the passed-in name
+ synop, desc = splitdoc(getdoc(object))
+ result = self.section('NAME', name + (synop and ' - ' + synop))
+ all = getattr(object, '__all__', None)
+ docloc = self.getdocloc(object)
+ if docloc is not None:
+ result = result + self.section('MODULE REFERENCE', docloc + """
+
+The following documentation is automatically generated from the Python
+source files. It may be incomplete, incorrect or include features that
+are considered implementation detail and may vary between Python
+implementations. When in doubt, consult the module reference at the
+location listed above.
+""")
+
+ if desc:
+ result = result + self.section('DESCRIPTION', desc)
+
+ classes = []
+ for key, value in inspect.getmembers(object, inspect.isclass):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None
+ or (inspect.getmodule(value) or object) is object):
+ if visiblename(key, all, object):
+ classes.append((key, value))
+ funcs = []
+ for key, value in inspect.getmembers(object, inspect.isroutine):
+ # if __all__ exists, believe it. Otherwise use old heuristic.
+ if (all is not None or
+ inspect.isbuiltin(value) or inspect.getmodule(value) is object):
+ if visiblename(key, all, object):
+ funcs.append((key, value))
+ data = []
+ for key, value in inspect.getmembers(object, isdata):
+ if visiblename(key, all, object):
+ data.append((key, value))
+
+ modpkgs = []
+ modpkgs_names = set()
+ if hasattr(object, '__path__'):
+ for importer, modname, ispkg in pkgutil.iter_modules(object.__path__):
+ modpkgs_names.add(modname)
+ if ispkg:
+ modpkgs.append(modname + ' (package)')
+ else:
+ modpkgs.append(modname)
+
+ modpkgs.sort()
+ result = result + self.section(
+ 'PACKAGE CONTENTS', '\n'.join(modpkgs))
+
+ # Detect submodules as sometimes created by C extensions
+ submodules = []
+ for key, value in inspect.getmembers(object, inspect.ismodule):
+ if value.__name__.startswith(name + '.') and key not in modpkgs_names:
+ submodules.append(key)
+ if submodules:
+ submodules.sort()
+ result = result + self.section(
+ 'SUBMODULES', '\n'.join(submodules))
+
+ if classes:
+ classlist = [value for key, value in classes]
+ contents = [self.formattree(
+ inspect.getclasstree(classlist, 1), name)]
+ for key, value in classes:
+ contents.append(self.document(value, key, name))
+ result = result + self.section('CLASSES', '\n'.join(contents))
+
+ if funcs:
+ contents = []
+ for key, value in funcs:
+ contents.append(self.document(value, key, name))
+ result = result + self.section('FUNCTIONS', '\n'.join(contents))
+
+ if data:
+ contents = []
+ for key, value in data:
+ contents.append(self.docother(value, key, name, maxlen=70))
+ result = result + self.section('DATA', '\n'.join(contents))
+
+ if hasattr(object, '__version__'):
+ version = str(object.__version__)
+ if version[:11] == '$' + 'Revision: ' and version[-1:] == '$':
+ version = version[11:-1].strip()
+ result = result + self.section('VERSION', version)
+ if hasattr(object, '__date__'):
+ result = result + self.section('DATE', str(object.__date__))
+ if hasattr(object, '__author__'):
+ result = result + self.section('AUTHOR', str(object.__author__))
+ if hasattr(object, '__credits__'):
+ result = result + self.section('CREDITS', str(object.__credits__))
+ try:
+ file = inspect.getabsfile(object)
+ except TypeError:
+ file = '(built-in)'
+ result = result + self.section('FILE', file)
+ return result
+
+ def docclass(self, object, name=None, mod=None, *ignored):
+ """Produce text documentation for a given class object."""
+ realname = object.__name__
+ name = name or realname
+ bases = object.__bases__
+
+ def makename(c, m=object.__module__):
+ return classname(c, m)
+
+ if name == realname:
+ title = 'class ' + self.bold(realname)
+ else:
+ title = self.bold(name) + ' = class ' + realname
+ if bases:
+ parents = map(makename, bases)
+ title = title + '(%s)' % ', '.join(parents)
+
+ doc = getdoc(object)
+ contents = doc and [doc + '\n'] or []
+ push = contents.append
+
+ # List the mro, if non-trivial.
+ mro = deque(inspect.getmro(object))
+ if len(mro) > 2:
+ push("Method resolution order:")
+ for base in mro:
+ push(' ' + makename(base))
+ push('')
+
+ # Cute little class to pump out a horizontal rule between sections.
+ class HorizontalRule:
+ def __init__(self):
+ self.needone = 0
+ def maybe(self):
+ if self.needone:
+ push('-' * 70)
+ self.needone = 1
+ hr = HorizontalRule()
+
+ def spill(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ try:
+ value = getattr(object, name)
+ except Exception:
+ # Some descriptors may meet a failure in their __get__.
+ # (bug #1785)
+ push(self._docdescriptor(name, value, mod))
+ else:
+ push(self.document(value,
+ name, mod, object))
+ return attrs
+
+ def spilldescriptors(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ push(self._docdescriptor(name, value, mod))
+ return attrs
+
+ def spilldata(msg, attrs, predicate):
+ ok, attrs = _split_list(attrs, predicate)
+ if ok:
+ hr.maybe()
+ push(msg)
+ for name, kind, homecls, value in ok:
+ if callable(value) or inspect.isdatadescriptor(value):
+ doc = getdoc(value)
+ else:
+ doc = None
+ try:
+ obj = getattr(object, name)
+ except AttributeError:
+ obj = homecls.__dict__[name]
+ push(self.docother(obj, name, mod, maxlen=70, doc=doc) +
+ '\n')
+ return attrs
+
+ attrs = [(name, kind, cls, value)
+ for name, kind, cls, value in classify_class_attrs(object)
+ if visiblename(name, obj=object)]
+
+ while attrs:
+ if mro:
+ thisclass = mro.popleft()
+ else:
+ thisclass = attrs[0][2]
+ attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass)
+
+ if thisclass is builtins.object:
+ attrs = inherited
+ continue
+ elif thisclass is object:
+ tag = "defined here"
+ else:
+ tag = "inherited from %s" % classname(thisclass,
+ object.__module__)
+
+ sort_attributes(attrs, object)
+
+ # Pump out the attrs, segregated by kind.
+ attrs = spill("Methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'method')
+ attrs = spill("Class methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'class method')
+ attrs = spill("Static methods %s:\n" % tag, attrs,
+ lambda t: t[1] == 'static method')
+ attrs = spilldescriptors("Data descriptors %s:\n" % tag, attrs,
+ lambda t: t[1] == 'data descriptor')
+ attrs = spilldata("Data and other attributes %s:\n" % tag, attrs,
+ lambda t: t[1] == 'data')
+
+ assert attrs == []
+ attrs = inherited
+
+ contents = '\n'.join(contents)
+ if not contents:
+ return title + '\n'
+ return title + '\n' + self.indent(contents.rstrip(), ' | ') + '\n'
+
+ def formatvalue(self, object):
+ """Format an argument default value as text."""
+ return '=' + self.repr(object)
+
+ def docroutine(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a function or method object."""
+ realname = object.__name__
+ name = name or realname
+ note = ''
+ skipdocs = 0
+ if _is_bound_method(object):
+ imclass = object.__self__.__class__
+ if cl:
+ if imclass is not cl:
+ note = ' from ' + classname(imclass, mod)
+ else:
+ if object.__self__ is not None:
+ note = ' method of %s instance' % classname(
+ object.__self__.__class__, mod)
+ else:
+ note = ' unbound %s method' % classname(imclass,mod)
+
+ if name == realname:
+ title = self.bold(realname)
+ else:
+ if cl and inspect.getattr_static(cl, realname, []) is object:
+ skipdocs = 1
+ title = self.bold(name) + ' = ' + realname
+ argspec = None
+
+ if inspect.isroutine(object):
+ try:
+ signature = inspect.signature(object)
+ except (ValueError, TypeError):
+ signature = None
+ if signature:
+ argspec = str(signature)
+ if realname == '<lambda>':
+ title = self.bold(name) + ' lambda '
+ # XXX lambda's won't usually have func_annotations['return']
+ # since the syntax doesn't support but it is possible.
+ # So removing parentheses isn't truly safe.
+ argspec = argspec[1:-1] # remove parentheses
+ if not argspec:
+ argspec = '(...)'
+ decl = title + argspec + note
+
+ if skipdocs:
+ return decl + '\n'
+ else:
+ doc = getdoc(object) or ''
+ return decl + '\n' + (doc and self.indent(doc).rstrip() + '\n')
+
+ def _docdescriptor(self, name, value, mod):
+ results = []
+ push = results.append
+
+ if name:
+ push(self.bold(name))
+ push('\n')
+ doc = getdoc(value) or ''
+ if doc:
+ push(self.indent(doc))
+ push('\n')
+ return ''.join(results)
+
+ def docproperty(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a property."""
+ return self._docdescriptor(name, object, mod)
+
+ def docdata(self, object, name=None, mod=None, cl=None):
+ """Produce text documentation for a data descriptor."""
+ return self._docdescriptor(name, object, mod)
+
+ def docother(self, object, name=None, mod=None, parent=None, maxlen=None, doc=None):
+ """Produce text documentation for a data object."""
+ repr = self.repr(object)
+ if maxlen:
+ line = (name and name + ' = ' or '') + repr
+ chop = maxlen - len(line)
+ if chop < 0: repr = repr[:chop] + '...'
+ line = (name and self.bold(name) + ' = ' or '') + repr
+ if doc is not None:
+ line += '\n' + self.indent(str(doc))
+ return line
+
+class _PlainTextDoc(TextDoc):
+ """Subclass of TextDoc which overrides string styling"""
+ def bold(self, text):
+ return text
+
+# --------------------------------------------------------- user interfaces
+
+def pager(text):
+ """The first time this is called, determine what kind of pager to use."""
+ global pager
+ pager = getpager()
+ pager(text)
+
+def getpager():
+ """Decide what method to use for paging through text."""
+ if not hasattr(sys.stdin, "isatty"):
+ return plainpager
+ if not hasattr(sys.stdout, "isatty"):
+ return plainpager
+ if not sys.stdin.isatty() or not sys.stdout.isatty():
+ return plainpager
+ use_pager = os.environ.get('MANPAGER') or os.environ.get('PAGER')
+ if use_pager:
+ if sys.platform == 'win32': # pipes completely broken in Windows
+ return lambda text: tempfilepager(plain(text), use_pager)
+ elif sys.platform == 'uefi':
+ return lambda text: tempfilepager(plain(text), use_pager)
+ elif os.environ.get('TERM') in ('dumb', 'emacs'):
+ return lambda text: pipepager(plain(text), use_pager)
+ else:
+ return lambda text: pipepager(text, use_pager)
+ if os.environ.get('TERM') in ('dumb', 'emacs'):
+ return plainpager
+ if sys.platform == 'uefi':
+ return plainpager
+ if sys.platform == 'win32':
+ return lambda text: tempfilepager(plain(text), 'more <')
+ if hasattr(os, 'system') and os.system('(less) 2>/dev/null') == 0:
+ return lambda text: pipepager(text, 'less')
+
+ import tempfile
+ (fd, filename) = tempfile.mkstemp()
+ os.close(fd)
+ try:
+ if hasattr(os, 'system') and os.system('more "%s"' % filename) == 0:
+ return lambda text: pipepager(text, 'more')
+ else:
+ return ttypager
+ finally:
+ os.unlink(filename)
+
+def plain(text):
+ """Remove boldface formatting from text."""
+ return re.sub('.\b', '', text)
+
+def pipepager(text, cmd):
+ """Page through text by feeding it to another program."""
+ import sys
+ if sys.platform != 'uefi':
+ import subprocess
+ proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)
+ try:
+ with io.TextIOWrapper(proc.stdin, errors='backslashreplace') as pipe:
+ try:
+ pipe.write(text)
+ except KeyboardInterrupt:
+ # We've hereby abandoned whatever text hasn't been written,
+ # but the pager is still in control of the terminal.
+ pass
+ except OSError:
+ pass # Ignore broken pipes caused by quitting the pager program.
+ while True:
+ try:
+ proc.wait()
+ break
+ except KeyboardInterrupt:
+ # Ignore ctl-c like the pager itself does. Otherwise the pager is
+ # left running and the terminal is in raw mode and unusable.
+ pass
+ else:
+ pipe = os.popen(cmd, 'w')
+ try:
+ pipe.write(_encode(text))
+ pipe.close()
+ except IOError:
+ pass # Ignore broken pipes caused by quitting the pager program.
+
+def tempfilepager(text, cmd):
+ """Page through text by invoking a program on a temporary file."""
+ import tempfile
+ filename = tempfile.mktemp()
+ with open(filename, 'w', errors='backslashreplace') as file:
+ file.write(text)
+ try:
+ os.system(cmd + ' "' + filename + '"')
+ finally:
+ os.unlink(filename)
+
+def _escape_stdout(text):
+ # Escape non-encodable characters to avoid encoding errors later
+ encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'
+ return text.encode(encoding, 'backslashreplace').decode(encoding)
+
+def ttypager(text):
+ """Page through text on a text terminal."""
+ lines = plain(_escape_stdout(text)).split('\n')
+ try:
+ import tty
+ fd = sys.stdin.fileno()
+ old = tty.tcgetattr(fd)
+ tty.setcbreak(fd)
+ getchar = lambda: sys.stdin.read(1)
+ except (ImportError, AttributeError, io.UnsupportedOperation):
+ tty = None
+ getchar = lambda: sys.stdin.readline()[:-1][:1]
+
+ try:
+ try:
+ h = int(os.environ.get('LINES', 0))
+ except ValueError:
+ h = 0
+ if h <= 1:
+ h = 25
+ r = inc = h - 1
+ sys.stdout.write('\n'.join(lines[:inc]) + '\n')
+ while lines[r:]:
+ sys.stdout.write('-- more --')
+ sys.stdout.flush()
+ c = getchar()
+
+ if c in ('q', 'Q'):
+ sys.stdout.write('\r \r')
+ break
+ elif c in ('\r', '\n'):
+ sys.stdout.write('\r \r' + lines[r] + '\n')
+ r = r + 1
+ continue
+ if c in ('b', 'B', '\x1b'):
+ r = r - inc - inc
+ if r < 0: r = 0
+ sys.stdout.write('\n' + '\n'.join(lines[r:r+inc]) + '\n')
+ r = r + inc
+
+ finally:
+ if tty:
+ tty.tcsetattr(fd, tty.TCSAFLUSH, old)
+
+def plainpager(text):
+ """Simply print unformatted text. This is the ultimate fallback."""
+ sys.stdout.write(plain(_escape_stdout(text)))
+
+def describe(thing):
+ """Produce a short description of the given thing."""
+ if inspect.ismodule(thing):
+ if thing.__name__ in sys.builtin_module_names:
+ return 'built-in module ' + thing.__name__
+ if hasattr(thing, '__path__'):
+ return 'package ' + thing.__name__
+ else:
+ return 'module ' + thing.__name__
+ if inspect.isbuiltin(thing):
+ return 'built-in function ' + thing.__name__
+ if inspect.isgetsetdescriptor(thing):
+ return 'getset descriptor %s.%s.%s' % (
+ thing.__objclass__.__module__, thing.__objclass__.__name__,
+ thing.__name__)
+ if inspect.ismemberdescriptor(thing):
+ return 'member descriptor %s.%s.%s' % (
+ thing.__objclass__.__module__, thing.__objclass__.__name__,
+ thing.__name__)
+ if inspect.isclass(thing):
+ return 'class ' + thing.__name__
+ if inspect.isfunction(thing):
+ return 'function ' + thing.__name__
+ if inspect.ismethod(thing):
+ return 'method ' + thing.__name__
+ return type(thing).__name__
+
+def locate(path, forceload=0):
+ """Locate an object by name or dotted path, importing as necessary."""
+ parts = [part for part in path.split('.') if part]
+ module, n = None, 0
+ while n < len(parts):
+ nextmodule = safeimport('.'.join(parts[:n+1]), forceload)
+ if nextmodule: module, n = nextmodule, n + 1
+ else: break
+ if module:
+ object = module
+ else:
+ object = builtins
+ for part in parts[n:]:
+ try:
+ object = getattr(object, part)
+ except AttributeError:
+ return None
+ return object
+
+# --------------------------------------- interactive interpreter interface
+
+text = TextDoc()
+plaintext = _PlainTextDoc()
+html = HTMLDoc()
+
+def resolve(thing, forceload=0):
+ """Given an object or a path to an object, get the object and its name."""
+ if isinstance(thing, str):
+ object = locate(thing, forceload)
+ if object is None:
+ raise ImportError('''\
+No Python documentation found for %r.
+Use help() to get the interactive help utility.
+Use help(str) for help on the str class.''' % thing)
+ return object, thing
+ else:
+ name = getattr(thing, '__name__', None)
+ return thing, name if isinstance(name, str) else None
+
+def render_doc(thing, title='Python Library Documentation: %s', forceload=0,
+ renderer=None):
+ """Render text documentation, given an object or a path to an object."""
+ if renderer is None:
+ renderer = text
+ object, name = resolve(thing, forceload)
+ desc = describe(object)
+ module = inspect.getmodule(object)
+ if name and '.' in name:
+ desc += ' in ' + name[:name.rfind('.')]
+ elif module and module is not object:
+ desc += ' in module ' + module.__name__
+
+ if not (inspect.ismodule(object) or
+ inspect.isclass(object) or
+ inspect.isroutine(object) or
+ inspect.isgetsetdescriptor(object) or
+ inspect.ismemberdescriptor(object) or
+ isinstance(object, property)):
+ # If the passed object is a piece of data or an instance,
+ # document its available methods instead of its value.
+ object = type(object)
+ desc += ' object'
+ return title % desc + '\n\n' + renderer.document(object, name)
+
+def doc(thing, title='Python Library Documentation: %s', forceload=0,
+ output=None):
+ """Display text documentation, given an object or a path to an object."""
+ try:
+ if output is None:
+ pager(render_doc(thing, title, forceload))
+ else:
+ output.write(render_doc(thing, title, forceload, plaintext))
+ except (ImportError, ErrorDuringImport) as value:
+ print(value)
+
+def writedoc(thing, forceload=0):
+ """Write HTML documentation to a file in the current directory."""
+ try:
+ object, name = resolve(thing, forceload)
+ page = html.page(describe(object), html.document(object, name))
+ with open(name + '.html', 'w', encoding='utf-8') as file:
+ file.write(page)
+ print('wrote', name + '.html')
+ except (ImportError, ErrorDuringImport) as value:
+ print(value)
+
+def writedocs(dir, pkgpath='', done=None):
+ """Write out HTML documentation for all modules in a directory tree."""
+ if done is None: done = {}
+ for importer, modname, ispkg in pkgutil.walk_packages([dir], pkgpath):
+ writedoc(modname)
+ return
+
+class Helper:
+
+ # These dictionaries map a topic name to either an alias, or a tuple
+ # (label, seealso-items). The "label" is the label of the corresponding
+ # section in the .rst file under Doc/ and an index into the dictionary
+ # in pydoc_data/topics.py.
+ #
+ # CAUTION: if you change one of these dictionaries, be sure to adapt the
+ # list of needed labels in Doc/tools/pyspecific.py and
+ # regenerate the pydoc_data/topics.py file by running
+ # make pydoc-topics
+ # in Doc/ and copying the output file into the Lib/ directory.
+
+ keywords = {
+ 'False': '',
+ 'None': '',
+ 'True': '',
+ 'and': 'BOOLEAN',
+ 'as': 'with',
+ 'assert': ('assert', ''),
+ 'break': ('break', 'while for'),
+ 'class': ('class', 'CLASSES SPECIALMETHODS'),
+ 'continue': ('continue', 'while for'),
+ 'def': ('function', ''),
+ 'del': ('del', 'BASICMETHODS'),
+ 'elif': 'if',
+ 'else': ('else', 'while for'),
+ 'except': 'try',
+ 'finally': 'try',
+ 'for': ('for', 'break continue while'),
+ 'from': 'import',
+ 'global': ('global', 'nonlocal NAMESPACES'),
+ 'if': ('if', 'TRUTHVALUE'),
+ 'import': ('import', 'MODULES'),
+ 'in': ('in', 'SEQUENCEMETHODS'),
+ 'is': 'COMPARISON',
+ 'lambda': ('lambda', 'FUNCTIONS'),
+ 'nonlocal': ('nonlocal', 'global NAMESPACES'),
+ 'not': 'BOOLEAN',
+ 'or': 'BOOLEAN',
+ 'pass': ('pass', ''),
+ 'raise': ('raise', 'EXCEPTIONS'),
+ 'return': ('return', 'FUNCTIONS'),
+ 'try': ('try', 'EXCEPTIONS'),
+ 'while': ('while', 'break continue if TRUTHVALUE'),
+ 'with': ('with', 'CONTEXTMANAGERS EXCEPTIONS yield'),
+ 'yield': ('yield', ''),
+ }
+ # Either add symbols to this dictionary or to the symbols dictionary
+ # directly: Whichever is easier. They are merged later.
+ _strprefixes = [p + q for p in ('b', 'f', 'r', 'u') for q in ("'", '"')]
+ _symbols_inverse = {
+ 'STRINGS' : ("'", "'''", '"', '"""', *_strprefixes),
+ 'OPERATORS' : ('+', '-', '*', '**', '/', '//', '%', '<<', '>>', '&',
+ '|', '^', '~', '<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'COMPARISON' : ('<', '>', '<=', '>=', '==', '!=', '<>'),
+ 'UNARY' : ('-', '~'),
+ 'AUGMENTEDASSIGNMENT' : ('+=', '-=', '*=', '/=', '%=', '&=', '|=',
+ '^=', '<<=', '>>=', '**=', '//='),
+ 'BITWISE' : ('<<', '>>', '&', '|', '^', '~'),
+ 'COMPLEX' : ('j', 'J')
+ }
+ symbols = {
+ '%': 'OPERATORS FORMATTING',
+ '**': 'POWER',
+ ',': 'TUPLES LISTS FUNCTIONS',
+ '.': 'ATTRIBUTES FLOAT MODULES OBJECTS',
+ '...': 'ELLIPSIS',
+ ':': 'SLICINGS DICTIONARYLITERALS',
+ '@': 'def class',
+ '\\': 'STRINGS',
+ '_': 'PRIVATENAMES',
+ '__': 'PRIVATENAMES SPECIALMETHODS',
+ '`': 'BACKQUOTES',
+ '(': 'TUPLES FUNCTIONS CALLS',
+ ')': 'TUPLES FUNCTIONS CALLS',
+ '[': 'LISTS SUBSCRIPTS SLICINGS',
+ ']': 'LISTS SUBSCRIPTS SLICINGS'
+ }
+ for topic, symbols_ in _symbols_inverse.items():
+ for symbol in symbols_:
+ topics = symbols.get(symbol, topic)
+ if topic not in topics:
+ topics = topics + ' ' + topic
+ symbols[symbol] = topics
+
+ topics = {
+ 'TYPES': ('types', 'STRINGS UNICODE NUMBERS SEQUENCES MAPPINGS '
+ 'FUNCTIONS CLASSES MODULES FILES inspect'),
+ 'STRINGS': ('strings', 'str UNICODE SEQUENCES STRINGMETHODS '
+ 'FORMATTING TYPES'),
+ 'STRINGMETHODS': ('string-methods', 'STRINGS FORMATTING'),
+ 'FORMATTING': ('formatstrings', 'OPERATORS'),
+ 'UNICODE': ('strings', 'encodings unicode SEQUENCES STRINGMETHODS '
+ 'FORMATTING TYPES'),
+ 'NUMBERS': ('numbers', 'INTEGER FLOAT COMPLEX TYPES'),
+ 'INTEGER': ('integers', 'int range'),
+ 'FLOAT': ('floating', 'float math'),
+ 'COMPLEX': ('imaginary', 'complex cmath'),
+ 'SEQUENCES': ('typesseq', 'STRINGMETHODS FORMATTING range LISTS'),
+ 'MAPPINGS': 'DICTIONARIES',
+ 'FUNCTIONS': ('typesfunctions', 'def TYPES'),
+ 'METHODS': ('typesmethods', 'class def CLASSES TYPES'),
+ 'CODEOBJECTS': ('bltin-code-objects', 'compile FUNCTIONS TYPES'),
+ 'TYPEOBJECTS': ('bltin-type-objects', 'types TYPES'),
+ 'FRAMEOBJECTS': 'TYPES',
+ 'TRACEBACKS': 'TYPES',
+ 'NONE': ('bltin-null-object', ''),
+ 'ELLIPSIS': ('bltin-ellipsis-object', 'SLICINGS'),
+ 'SPECIALATTRIBUTES': ('specialattrs', ''),
+ 'CLASSES': ('types', 'class SPECIALMETHODS PRIVATENAMES'),
+ 'MODULES': ('typesmodules', 'import'),
+ 'PACKAGES': 'import',
+ 'EXPRESSIONS': ('operator-summary', 'lambda or and not in is BOOLEAN '
+ 'COMPARISON BITWISE SHIFTING BINARY FORMATTING POWER '
+ 'UNARY ATTRIBUTES SUBSCRIPTS SLICINGS CALLS TUPLES '
+ 'LISTS DICTIONARIES'),
+ 'OPERATORS': 'EXPRESSIONS',
+ 'PRECEDENCE': 'EXPRESSIONS',
+ 'OBJECTS': ('objects', 'TYPES'),
+ 'SPECIALMETHODS': ('specialnames', 'BASICMETHODS ATTRIBUTEMETHODS '
+ 'CALLABLEMETHODS SEQUENCEMETHODS MAPPINGMETHODS '
+ 'NUMBERMETHODS CLASSES'),
+ 'BASICMETHODS': ('customization', 'hash repr str SPECIALMETHODS'),
+ 'ATTRIBUTEMETHODS': ('attribute-access', 'ATTRIBUTES SPECIALMETHODS'),
+ 'CALLABLEMETHODS': ('callable-types', 'CALLS SPECIALMETHODS'),
+ 'SEQUENCEMETHODS': ('sequence-types', 'SEQUENCES SEQUENCEMETHODS '
+ 'SPECIALMETHODS'),
+ 'MAPPINGMETHODS': ('sequence-types', 'MAPPINGS SPECIALMETHODS'),
+ 'NUMBERMETHODS': ('numeric-types', 'NUMBERS AUGMENTEDASSIGNMENT '
+ 'SPECIALMETHODS'),
+ 'EXECUTION': ('execmodel', 'NAMESPACES DYNAMICFEATURES EXCEPTIONS'),
+ 'NAMESPACES': ('naming', 'global nonlocal ASSIGNMENT DELETION DYNAMICFEATURES'),
+ 'DYNAMICFEATURES': ('dynamic-features', ''),
+ 'SCOPING': 'NAMESPACES',
+ 'FRAMES': 'NAMESPACES',
+ 'EXCEPTIONS': ('exceptions', 'try except finally raise'),
+ 'CONVERSIONS': ('conversions', ''),
+ 'IDENTIFIERS': ('identifiers', 'keywords SPECIALIDENTIFIERS'),
+ 'SPECIALIDENTIFIERS': ('id-classes', ''),
+ 'PRIVATENAMES': ('atom-identifiers', ''),
+ 'LITERALS': ('atom-literals', 'STRINGS NUMBERS TUPLELITERALS '
+ 'LISTLITERALS DICTIONARYLITERALS'),
+ 'TUPLES': 'SEQUENCES',
+ 'TUPLELITERALS': ('exprlists', 'TUPLES LITERALS'),
+ 'LISTS': ('typesseq-mutable', 'LISTLITERALS'),
+ 'LISTLITERALS': ('lists', 'LISTS LITERALS'),
+ 'DICTIONARIES': ('typesmapping', 'DICTIONARYLITERALS'),
+ 'DICTIONARYLITERALS': ('dict', 'DICTIONARIES LITERALS'),
+ 'ATTRIBUTES': ('attribute-references', 'getattr hasattr setattr ATTRIBUTEMETHODS'),
+ 'SUBSCRIPTS': ('subscriptions', 'SEQUENCEMETHODS'),
+ 'SLICINGS': ('slicings', 'SEQUENCEMETHODS'),
+ 'CALLS': ('calls', 'EXPRESSIONS'),
+ 'POWER': ('power', 'EXPRESSIONS'),
+ 'UNARY': ('unary', 'EXPRESSIONS'),
+ 'BINARY': ('binary', 'EXPRESSIONS'),
+ 'SHIFTING': ('shifting', 'EXPRESSIONS'),
+ 'BITWISE': ('bitwise', 'EXPRESSIONS'),
+ 'COMPARISON': ('comparisons', 'EXPRESSIONS BASICMETHODS'),
+ 'BOOLEAN': ('booleans', 'EXPRESSIONS TRUTHVALUE'),
+ 'ASSERTION': 'assert',
+ 'ASSIGNMENT': ('assignment', 'AUGMENTEDASSIGNMENT'),
+ 'AUGMENTEDASSIGNMENT': ('augassign', 'NUMBERMETHODS'),
+ 'DELETION': 'del',
+ 'RETURNING': 'return',
+ 'IMPORTING': 'import',
+ 'CONDITIONAL': 'if',
+ 'LOOPING': ('compound', 'for while break continue'),
+ 'TRUTHVALUE': ('truth', 'if while and or not BASICMETHODS'),
+ 'DEBUGGING': ('debugger', 'pdb'),
+ 'CONTEXTMANAGERS': ('context-managers', 'with'),
+ }
+
+ def __init__(self, input=None, output=None):
+ self._input = input
+ self._output = output
+
+ input = property(lambda self: self._input or sys.stdin)
+ output = property(lambda self: self._output or sys.stdout)
+
+ def __repr__(self):
+ if inspect.stack()[1][3] == '?':
+ self()
+ return ''
+ return '<%s.%s instance>' % (self.__class__.__module__,
+ self.__class__.__qualname__)
+
+ _GoInteractive = object()
+ def __call__(self, request=_GoInteractive):
+ if request is not self._GoInteractive:
+ self.help(request)
+ else:
+ self.intro()
+ self.interact()
+ self.output.write('''
+You are now leaving help and returning to the Python interpreter.
+If you want to ask for help on a particular object directly from the
+interpreter, you can type "help(object)". Executing "help('string')"
+has the same effect as typing a particular string at the help> prompt.
+''')
+
+ def interact(self):
+ self.output.write('\n')
+ while True:
+ try:
+ request = self.getline('help> ')
+ if not request: break
+ except (KeyboardInterrupt, EOFError):
+ break
+ request = request.strip()
+
+ # Make sure significant trailing quoting marks of literals don't
+ # get deleted while cleaning input
+ if (len(request) > 2 and request[0] == request[-1] in ("'", '"')
+ and request[0] not in request[1:-1]):
+ request = request[1:-1]
+ if request.lower() in ('q', 'quit'): break
+ if request == 'help':
+ self.intro()
+ else:
+ self.help(request)
+
+ def getline(self, prompt):
+ """Read one line, using input() when appropriate."""
+ if self.input is sys.stdin:
+ return input(prompt)
+ else:
+ self.output.write(prompt)
+ self.output.flush()
+ return self.input.readline()
+
+ def help(self, request):
+ if type(request) is type(''):
+ request = request.strip()
+ if request == 'keywords': self.listkeywords()
+ elif request == 'symbols': self.listsymbols()
+ elif request == 'topics': self.listtopics()
+ elif request == 'modules': self.listmodules()
+ elif request[:8] == 'modules ':
+ self.listmodules(request.split()[1])
+ elif request in self.symbols: self.showsymbol(request)
+ elif request in ['True', 'False', 'None']:
+ # special case these keywords since they are objects too
+ doc(eval(request), 'Help on %s:')
+ elif request in self.keywords: self.showtopic(request)
+ elif request in self.topics: self.showtopic(request)
+ elif request: doc(request, 'Help on %s:', output=self._output)
+ else: doc(str, 'Help on %s:', output=self._output)
+ elif isinstance(request, Helper): self()
+ else: doc(request, 'Help on %s:', output=self._output)
+ self.output.write('\n')
+
+ def intro(self):
+ self.output.write('''
+Welcome to Python {0}'s help utility!
+
+If this is your first time using Python, you should definitely check out
+the tutorial on the Internet at https://docs.python.org/{0}/tutorial/.
+
+Enter the name of any module, keyword, or topic to get help on writing
+Python programs and using Python modules. To quit this help utility and
+return to the interpreter, just type "quit".
+
+To get a list of available modules, keywords, symbols, or topics, type
+"modules", "keywords", "symbols", or "topics". Each module also comes
+with a one-line summary of what it does; to list the modules whose name
+or summary contain a given string such as "spam", type "modules spam".
+'''.format('%d.%d' % sys.version_info[:2]))
+
+ def list(self, items, columns=4, width=80):
+ items = list(sorted(items))
+ colw = width // columns
+ rows = (len(items) + columns - 1) // columns
+ for row in range(rows):
+ for col in range(columns):
+ i = col * rows + row
+ if i < len(items):
+ self.output.write(items[i])
+ if col < columns - 1:
+ self.output.write(' ' + ' ' * (colw - 1 - len(items[i])))
+ self.output.write('\n')
+
+ def listkeywords(self):
+ self.output.write('''
+Here is a list of the Python keywords. Enter any keyword to get more help.
+
+''')
+ self.list(self.keywords.keys())
+
+ def listsymbols(self):
+ self.output.write('''
+Here is a list of the punctuation symbols which Python assigns special meaning
+to. Enter any symbol to get more help.
+
+''')
+ self.list(self.symbols.keys())
+
+ def listtopics(self):
+ self.output.write('''
+Here is a list of available topics. Enter any topic name to get more help.
+
+''')
+ self.list(self.topics.keys())
+
+ def showtopic(self, topic, more_xrefs=''):
+ try:
+ import pydoc_data.topics
+ except ImportError:
+ self.output.write('''
+Sorry, topic and keyword documentation is not available because the
+module "pydoc_data.topics" could not be found.
+''')
+ return
+ target = self.topics.get(topic, self.keywords.get(topic))
+ if not target:
+ self.output.write('no documentation found for %s\n' % repr(topic))
+ return
+ if type(target) is type(''):
+ return self.showtopic(target, more_xrefs)
+
+ label, xrefs = target
+ try:
+ doc = pydoc_data.topics.topics[label]
+ except KeyError:
+ self.output.write('no documentation found for %s\n' % repr(topic))
+ return
+ doc = doc.strip() + '\n'
+ if more_xrefs:
+ xrefs = (xrefs or '') + ' ' + more_xrefs
+ if xrefs:
+ import textwrap
+ text = 'Related help topics: ' + ', '.join(xrefs.split()) + '\n'
+ wrapped_text = textwrap.wrap(text, 72)
+ doc += '\n%s\n' % '\n'.join(wrapped_text)
+ pager(doc)
+
+ def _gettopic(self, topic, more_xrefs=''):
+ """Return unbuffered tuple of (topic, xrefs).
+
+ If an error occurs here, the exception is caught and displayed by
+ the url handler.
+
+ This function duplicates the showtopic method but returns its
+ result directly so it can be formatted for display in an html page.
+ """
+ try:
+ import pydoc_data.topics
+ except ImportError:
+ return('''
+Sorry, topic and keyword documentation is not available because the
+module "pydoc_data.topics" could not be found.
+''' , '')
+ target = self.topics.get(topic, self.keywords.get(topic))
+ if not target:
+ raise ValueError('could not find topic')
+ if isinstance(target, str):
+ return self._gettopic(target, more_xrefs)
+ label, xrefs = target
+ doc = pydoc_data.topics.topics[label]
+ if more_xrefs:
+ xrefs = (xrefs or '') + ' ' + more_xrefs
+ return doc, xrefs
+
+ def showsymbol(self, symbol):
+ target = self.symbols[symbol]
+ topic, _, xrefs = target.partition(' ')
+ self.showtopic(topic, xrefs)
+
+ def listmodules(self, key=''):
+ if key:
+ self.output.write('''
+Here is a list of modules whose name or summary contains '{}'.
+If there are any, enter a module name to get more help.
+
+'''.format(key))
+ apropos(key)
+ else:
+ self.output.write('''
+Please wait a moment while I gather a list of all available modules...
+
+''')
+ modules = {}
+ def callback(path, modname, desc, modules=modules):
+ if modname and modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ if modname.find('.') < 0:
+ modules[modname] = 1
+ def onerror(modname):
+ callback(None, modname, None)
+ ModuleScanner().run(callback, onerror=onerror)
+ self.list(modules.keys())
+ self.output.write('''
+Enter any module name to get more help. Or, type "modules spam" to search
+for modules whose name or summary contain the string "spam".
+''')
+
+help = Helper()
+
+class ModuleScanner:
+ """An interruptible scanner that searches module synopses."""
+
+ def run(self, callback, key=None, completer=None, onerror=None):
+ if key: key = key.lower()
+ self.quit = False
+ seen = {}
+
+ for modname in sys.builtin_module_names:
+ if modname != '__main__':
+ seen[modname] = 1
+ if key is None:
+ callback(None, modname, '')
+ else:
+ name = __import__(modname).__doc__ or ''
+ desc = name.split('\n')[0]
+ name = modname + ' - ' + desc
+ if name.lower().find(key) >= 0:
+ callback(None, modname, desc)
+
+ for importer, modname, ispkg in pkgutil.walk_packages(onerror=onerror):
+ if self.quit:
+ break
+
+ if key is None:
+ callback(None, modname, '')
+ else:
+ try:
+ spec = pkgutil._get_spec(importer, modname)
+ except SyntaxError:
+ # raised by tests for bad coding cookies or BOM
+ continue
+ loader = spec.loader
+ if hasattr(loader, 'get_source'):
+ try:
+ source = loader.get_source(modname)
+ except Exception:
+ if onerror:
+ onerror(modname)
+ continue
+ desc = source_synopsis(io.StringIO(source)) or ''
+ if hasattr(loader, 'get_filename'):
+ path = loader.get_filename(modname)
+ else:
+ path = None
+ else:
+ try:
+ module = importlib._bootstrap._load(spec)
+ except ImportError:
+ if onerror:
+ onerror(modname)
+ continue
+ desc = module.__doc__.splitlines()[0] if module.__doc__ else ''
+ path = getattr(module,'__file__',None)
+ name = modname + ' - ' + desc
+ if name.lower().find(key) >= 0:
+ callback(path, modname, desc)
+
+ if completer:
+ completer()
+
+def apropos(key):
+ """Print all the one-line module summaries that contain a substring."""
+ def callback(path, modname, desc):
+ if modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ print(modname, desc and '- ' + desc)
+ def onerror(modname):
+ pass
+ with warnings.catch_warnings():
+ warnings.filterwarnings('ignore') # ignore problems during import
+ ModuleScanner().run(callback, key, onerror=onerror)
+
+# --------------------------------------- enhanced Web browser interface
+
+def _start_server(urlhandler, port):
+ """Start an HTTP server thread on a specific port.
+
+ Start an HTML/text server thread, so HTML or text documents can be
+ browsed dynamically and interactively with a Web browser. Example use:
+
+ >>> import time
+ >>> import pydoc
+
+ Define a URL handler. To determine what the client is asking
+ for, check the URL and content_type.
+
+ Then get or generate some text or HTML code and return it.
+
+ >>> def my_url_handler(url, content_type):
+ ... text = 'the URL sent was: (%s, %s)' % (url, content_type)
+ ... return text
+
+ Start server thread on port 0.
+ If you use port 0, the server will pick a random port number.
+ You can then use serverthread.port to get the port number.
+
+ >>> port = 0
+ >>> serverthread = pydoc._start_server(my_url_handler, port)
+
+ Check that the server is really started. If it is, open browser
+ and get first page. Use serverthread.url as the starting page.
+
+ >>> if serverthread.serving:
+ ... import webbrowser
+
+ The next two lines are commented out so a browser doesn't open if
+ doctest is run on this module.
+
+ #... webbrowser.open(serverthread.url)
+ #True
+
+ Let the server do its thing. We just need to monitor its status.
+ Use time.sleep so the loop doesn't hog the CPU.
+
+ >>> starttime = time.time()
+ >>> timeout = 1 #seconds
+
+ This is a short timeout for testing purposes.
+
+ >>> while serverthread.serving:
+ ... time.sleep(.01)
+ ... if serverthread.serving and time.time() - starttime > timeout:
+ ... serverthread.stop()
+ ... break
+
+ Print any errors that may have occurred.
+
+ >>> print(serverthread.error)
+ None
+ """
+ import http.server
+ import email.message
+ import select
+ import threading
+
+ class DocHandler(http.server.BaseHTTPRequestHandler):
+
+ def do_GET(self):
+ """Process a request from an HTML browser.
+
+ The URL received is in self.path.
+ Get an HTML page from self.urlhandler and send it.
+ """
+ if self.path.endswith('.css'):
+ content_type = 'text/css'
+ else:
+ content_type = 'text/html'
+ self.send_response(200)
+ self.send_header('Content-Type', '%s; charset=UTF-8' % content_type)
+ self.end_headers()
+ self.wfile.write(self.urlhandler(
+ self.path, content_type).encode('utf-8'))
+
+ def log_message(self, *args):
+ # Don't log messages.
+ pass
+
+ class DocServer(http.server.HTTPServer):
+
+ def __init__(self, port, callback):
+ self.host = 'localhost'
+ self.address = (self.host, port)
+ self.callback = callback
+ self.base.__init__(self, self.address, self.handler)
+ self.quit = False
+
+ def serve_until_quit(self):
+ while not self.quit:
+ rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
+ if rd:
+ self.handle_request()
+ self.server_close()
+
+ def server_activate(self):
+ self.base.server_activate(self)
+ if self.callback:
+ self.callback(self)
+
+ class ServerThread(threading.Thread):
+
+ def __init__(self, urlhandler, port):
+ self.urlhandler = urlhandler
+ self.port = int(port)
+ threading.Thread.__init__(self)
+ self.serving = False
+ self.error = None
+
+ def run(self):
+ """Start the server."""
+ try:
+ DocServer.base = http.server.HTTPServer
+ DocServer.handler = DocHandler
+ DocHandler.MessageClass = email.message.Message
+ DocHandler.urlhandler = staticmethod(self.urlhandler)
+ docsvr = DocServer(self.port, self.ready)
+ self.docserver = docsvr
+ docsvr.serve_until_quit()
+ except Exception as e:
+ self.error = e
+
+ def ready(self, server):
+ self.serving = True
+ self.host = server.host
+ self.port = server.server_port
+ self.url = 'http://%s:%d/' % (self.host, self.port)
+
+ def stop(self):
+ """Stop the server and this thread nicely"""
+ self.docserver.quit = True
+ self.join()
+ # explicitly break a reference cycle: DocServer.callback
+ # has indirectly a reference to ServerThread.
+ self.docserver = None
+ self.serving = False
+ self.url = None
+
+ thread = ServerThread(urlhandler, port)
+ thread.start()
+ # Wait until thread.serving is True to make sure we are
+ # really up before returning.
+ while not thread.error and not thread.serving:
+ time.sleep(.01)
+ return thread
+
+
+def _url_handler(url, content_type="text/html"):
+ """The pydoc url handler for use with the pydoc server.
+
+ If the content_type is 'text/css', the _pydoc.css style
+ sheet is read and returned if it exits.
+
+ If the content_type is 'text/html', then the result of
+ get_html_page(url) is returned.
+ """
+ class _HTMLDoc(HTMLDoc):
+
+ def page(self, title, contents):
+ """Format an HTML page."""
+ css_path = "pydoc_data/_pydoc.css"
+ css_link = (
+ '<link rel="stylesheet" type="text/css" href="%s">' %
+ css_path)
+ return '''\
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Pydoc: %s</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+%s</head><body bgcolor="#f0f0f8">%s<div style="clear:both;padding-top:.5em;">%s</div>
+</body></html>''' % (title, css_link, html_navbar(), contents)
+
+ def filelink(self, url, path):
+ return '<a href="getfile?key=%s">%s</a>' % (url, path)
+
+
+ html = _HTMLDoc()
+
+ def html_navbar():
+ version = html.escape("%s [%s, %s]" % (platform.python_version(),
+ platform.python_build()[0],
+ platform.python_compiler()))
+ return """
+ <div style='float:left'>
+ Python %s<br>%s
+ </div>
+ <div style='float:right'>
+ <div style='text-align:center'>
+ <a href="index.html">Module Index</a>
+ : <a href="topics.html">Topics</a>
+ : <a href="keywords.html">Keywords</a>
+ </div>
+ <div>
+ <form action="get" style='display:inline;'>
+ <input type=text name=key size=15>
+ <input type=submit value="Get">
+ </form>&nbsp;
+ <form action="search" style='display:inline;'>
+ <input type=text name=key size=15>
+ <input type=submit value="Search">
+ </form>
+ </div>
+ </div>
+ """ % (version, html.escape(platform.platform(terse=True)))
+
+ def html_index():
+ """Module Index page."""
+
+ def bltinlink(name):
+ return '<a href="%s.html">%s</a>' % (name, name)
+
+ heading = html.heading(
+ '<big><big><strong>Index of Modules</strong></big></big>',
+ '#ffffff', '#7799ee')
+ names = [name for name in sys.builtin_module_names
+ if name != '__main__']
+ contents = html.multicolumn(names, bltinlink)
+ contents = [heading, '<p>' + html.bigsection(
+ 'Built-in Modules', '#ffffff', '#ee77aa', contents)]
+
+ seen = {}
+ for dir in sys.path:
+ contents.append(html.index(dir, seen))
+
+ contents.append(
+ '<p align=right><font color="#909090" face="helvetica,'
+ 'arial"><strong>pydoc</strong> by Ka-Ping Yee'
+ '&lt;ping@lfw.org&gt;</font>')
+ return 'Index of Modules', ''.join(contents)
+
+ def html_search(key):
+ """Search results page."""
+ # scan for modules
+ search_result = []
+
+ def callback(path, modname, desc):
+ if modname[-9:] == '.__init__':
+ modname = modname[:-9] + ' (package)'
+ search_result.append((modname, desc and '- ' + desc))
+
+ with warnings.catch_warnings():
+ warnings.filterwarnings('ignore') # ignore problems during import
+ def onerror(modname):
+ pass
+ ModuleScanner().run(callback, key, onerror=onerror)
+
+ # format page
+ def bltinlink(name):
+ return '<a href="%s.html">%s</a>' % (name, name)
+
+ results = []
+ heading = html.heading(
+ '<big><big><strong>Search Results</strong></big></big>',
+ '#ffffff', '#7799ee')
+ for name, desc in search_result:
+ results.append(bltinlink(name) + desc)
+ contents = heading + html.bigsection(
+ 'key = %s' % key, '#ffffff', '#ee77aa', '<br>'.join(results))
+ return 'Search Results', contents
+
+ def html_getfile(path):
+ """Get and display a source file listing safely."""
+ path = urllib.parse.unquote(path)
+ with tokenize.open(path) as fp:
+ lines = html.escape(fp.read())
+ body = '<pre>%s</pre>' % lines
+ heading = html.heading(
+ '<big><big><strong>File Listing</strong></big></big>',
+ '#ffffff', '#7799ee')
+ contents = heading + html.bigsection(
+ 'File: %s' % path, '#ffffff', '#ee77aa', body)
+ return 'getfile %s' % path, contents
+
+ def html_topics():
+ """Index of topic texts available."""
+
+ def bltinlink(name):
+ return '<a href="topic?key=%s">%s</a>' % (name, name)
+
+ heading = html.heading(
+ '<big><big><strong>INDEX</strong></big></big>',
+ '#ffffff', '#7799ee')
+ names = sorted(Helper.topics.keys())
+
+ contents = html.multicolumn(names, bltinlink)
+ contents = heading + html.bigsection(
+ 'Topics', '#ffffff', '#ee77aa', contents)
+ return 'Topics', contents
+
+ def html_keywords():
+ """Index of keywords."""
+ heading = html.heading(
+ '<big><big><strong>INDEX</strong></big></big>',
+ '#ffffff', '#7799ee')
+ names = sorted(Helper.keywords.keys())
+
+ def bltinlink(name):
+ return '<a href="topic?key=%s">%s</a>' % (name, name)
+
+ contents = html.multicolumn(names, bltinlink)
+ contents = heading + html.bigsection(
+ 'Keywords', '#ffffff', '#ee77aa', contents)
+ return 'Keywords', contents
+
+ def html_topicpage(topic):
+ """Topic or keyword help page."""
+ buf = io.StringIO()
+ htmlhelp = Helper(buf, buf)
+ contents, xrefs = htmlhelp._gettopic(topic)
+ if topic in htmlhelp.keywords:
+ title = 'KEYWORD'
+ else:
+ title = 'TOPIC'
+ heading = html.heading(
+ '<big><big><strong>%s</strong></big></big>' % title,
+ '#ffffff', '#7799ee')
+ contents = '<pre>%s</pre>' % html.markup(contents)
+ contents = html.bigsection(topic , '#ffffff','#ee77aa', contents)
+ if xrefs:
+ xrefs = sorted(xrefs.split())
+
+ def bltinlink(name):
+ return '<a href="topic?key=%s">%s</a>' % (name, name)
+
+ xrefs = html.multicolumn(xrefs, bltinlink)
+ xrefs = html.section('Related help topics: ',
+ '#ffffff', '#ee77aa', xrefs)
+ return ('%s %s' % (title, topic),
+ ''.join((heading, contents, xrefs)))
+
+ def html_getobj(url):
+ obj = locate(url, forceload=1)
+ if obj is None and url != 'None':
+ raise ValueError('could not find object')
+ title = describe(obj)
+ content = html.document(obj, url)
+ return title, content
+
+ def html_error(url, exc):
+ heading = html.heading(
+ '<big><big><strong>Error</strong></big></big>',
+ '#ffffff', '#7799ee')
+ contents = '<br>'.join(html.escape(line) for line in
+ format_exception_only(type(exc), exc))
+ contents = heading + html.bigsection(url, '#ffffff', '#bb0000',
+ contents)
+ return "Error - %s" % url, contents
+
+ def get_html_page(url):
+ """Generate an HTML page for url."""
+ complete_url = url
+ if url.endswith('.html'):
+ url = url[:-5]
+ try:
+ if url in ("", "index"):
+ title, content = html_index()
+ elif url == "topics":
+ title, content = html_topics()
+ elif url == "keywords":
+ title, content = html_keywords()
+ elif '=' in url:
+ op, _, url = url.partition('=')
+ if op == "search?key":
+ title, content = html_search(url)
+ elif op == "getfile?key":
+ title, content = html_getfile(url)
+ elif op == "topic?key":
+ # try topics first, then objects.
+ try:
+ title, content = html_topicpage(url)
+ except ValueError:
+ title, content = html_getobj(url)
+ elif op == "get?key":
+ # try objects first, then topics.
+ if url in ("", "index"):
+ title, content = html_index()
+ else:
+ try:
+ title, content = html_getobj(url)
+ except ValueError:
+ title, content = html_topicpage(url)
+ else:
+ raise ValueError('bad pydoc url')
+ else:
+ title, content = html_getobj(url)
+ except Exception as exc:
+ # Catch any errors and display them in an error page.
+ title, content = html_error(complete_url, exc)
+ return html.page(title, content)
+
+ if url.startswith('/'):
+ url = url[1:]
+ if content_type == 'text/css':
+ path_here = os.path.dirname(os.path.realpath(__file__))
+ css_path = os.path.join(path_here, url)
+ with open(css_path) as fp:
+ return ''.join(fp.readlines())
+ elif content_type == 'text/html':
+ return get_html_page(url)
+ # Errors outside the url handler are caught by the server.
+ raise TypeError('unknown content type %r for url %s' % (content_type, url))
+
+
+def browse(port=0, *, open_browser=True):
+ """Start the enhanced pydoc Web server and open a Web browser.
+
+ Use port '0' to start the server on an arbitrary port.
+ Set open_browser to False to suppress opening a browser.
+ """
+ import webbrowser
+ serverthread = _start_server(_url_handler, port)
+ if serverthread.error:
+ print(serverthread.error)
+ return
+ if serverthread.serving:
+ server_help_msg = 'Server commands: [b]rowser, [q]uit'
+ if open_browser:
+ webbrowser.open(serverthread.url)
+ try:
+ print('Server ready at', serverthread.url)
+ print(server_help_msg)
+ while serverthread.serving:
+ cmd = input('server> ')
+ cmd = cmd.lower()
+ if cmd == 'q':
+ break
+ elif cmd == 'b':
+ webbrowser.open(serverthread.url)
+ else:
+ print(server_help_msg)
+ except (KeyboardInterrupt, EOFError):
+ print()
+ finally:
+ if serverthread.serving:
+ serverthread.stop()
+ print('Server stopped')
+
+
+# -------------------------------------------------- command-line interface
+
+def ispath(x):
+ return isinstance(x, str) and x.find(os.sep) >= 0
+
+def cli():
+ """Command-line interface (looks at sys.argv to decide what to do)."""
+ import getopt
+ class BadUsage(Exception): pass
+
+ # Scripts don't get the current directory in their path by default
+ # unless they are run with the '-m' switch
+ if '' not in sys.path:
+ scriptdir = os.path.dirname(sys.argv[0])
+ if scriptdir in sys.path:
+ sys.path.remove(scriptdir)
+ sys.path.insert(0, '.')
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'bk:p:w')
+ writing = False
+ start_server = False
+ open_browser = False
+ port = None
+ for opt, val in opts:
+ if opt == '-b':
+ start_server = True
+ open_browser = True
+ if opt == '-k':
+ apropos(val)
+ return
+ if opt == '-p':
+ start_server = True
+ port = val
+ if opt == '-w':
+ writing = True
+
+ if start_server:
+ if port is None:
+ port = 0
+ browse(port, open_browser=open_browser)
+ return
+
+ if not args: raise BadUsage
+ for arg in args:
+ if ispath(arg) and not os.path.exists(arg):
+ print('file %r does not exist' % arg)
+ break
+ try:
+ if ispath(arg) and os.path.isfile(arg):
+ arg = importfile(arg)
+ if writing:
+ if ispath(arg) and os.path.isdir(arg):
+ writedocs(arg)
+ else:
+ writedoc(arg)
+ else:
+ help.help(arg)
+ except ErrorDuringImport as value:
+ print(value)
+
+ except (getopt.error, BadUsage):
+ cmd = os.path.splitext(os.path.basename(sys.argv[0]))[0]
+ print("""pydoc - the Python documentation tool
+
+{cmd} <name> ...
+ Show text documentation on something. <name> may be the name of a
+ Python keyword, topic, function, module, or package, or a dotted
+ reference to a class or function within a module or module in a
+ package. If <name> contains a '{sep}', it is used as the path to a
+ Python source file to document. If name is 'keywords', 'topics',
+ or 'modules', a listing of these things is displayed.
+
+{cmd} -k <keyword>
+ Search for a keyword in the synopsis lines of all available modules.
+
+{cmd} -p <port>
+ Start an HTTP server on the given port on the local machine. Port
+ number 0 can be used to get an arbitrary unused port.
+
+{cmd} -b
+ Start an HTTP server on an arbitrary unused port and open a Web browser
+ to interactively browse documentation. The -p option can be used with
+ the -b option to explicitly specify the server port.
+
+{cmd} -w <name> ...
+ Write out the HTML documentation for a module to a file in the current
+ directory. If <name> contains a '{sep}', it is treated as a filename; if
+ it names a directory, documentation is written for all the contents.
+""".format(cmd=cmd, sep=os.sep))
+
+if __name__ == '__main__':
+ cli()
diff --git a/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/shutil.py b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/shutil.py
new file mode 100644
index 00000000..d34a9d0f
--- /dev/null
+++ b/AppPkg/Applications/Python/Python-3.6.8/PyMod-3.6.8/Lib/shutil.py
@@ -0,0 +1,1160 @@
+"""Utility functions for copying and archiving files and directory trees.
+
+XXX The functions here don't copy the resource fork or other metadata on Mac.
+
+"""
+
+import os
+import sys
+import stat
+import fnmatch
+import collections
+import errno
+
+try:
+ import zlib
+ del zlib
+ _ZLIB_SUPPORTED = True
+except ImportError:
+ _ZLIB_SUPPORTED = False
+
+try:
+ import bz2
+ del bz2
+ _BZ2_SUPPORTED = True
+except ImportError:
+ _BZ2_SUPPORTED = False
+
+try:
+ import lzma
+ del lzma
+ _LZMA_SUPPORTED = True
+except ImportError:
+ _LZMA_SUPPORTED = False
+
+try:
+ from pwd import getpwnam
+except ImportError:
+ getpwnam = None
+
+try:
+ from grp import getgrnam
+except ImportError:
+ getgrnam = None
+
+__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2",
+ "copytree", "move", "rmtree", "Error", "SpecialFileError",
+ "ExecError", "make_archive", "get_archive_formats",
+ "register_archive_format", "unregister_archive_format",
+ "get_unpack_formats", "register_unpack_format",
+ "unregister_unpack_format", "unpack_archive",
+ "ignore_patterns", "chown", "which", "get_terminal_size",
+ "SameFileError"]
+ # disk_usage is added later, if available on the platform
+
+class Error(OSError):
+ pass
+
+class SameFileError(Error):
+ """Raised when source and destination are the same file."""
+
+class SpecialFileError(OSError):
+ """Raised when trying to do a kind of operation (e.g. copying) which is
+ not supported on a special file (e.g. a named pipe)"""
+
+class ExecError(OSError):
+ """Raised when a command could not be executed"""
+
+class ReadError(OSError):
+ """Raised when an archive cannot be read"""
+
+class RegistryError(Exception):
+ """Raised when a registry operation with the archiving
+ and unpacking registries fails"""
+
+
+def copyfileobj(fsrc, fdst, length=16*1024):
+ """copy data from file-like object fsrc to file-like object fdst"""
+ while 1:
+ buf = fsrc.read(length)
+ if not buf:
+ break
+ fdst.write(buf)
+
+def _samefile(src, dst):
+ # Macintosh, Unix.
+ if hasattr(os.path, 'samefile'):
+ try:
+ return os.path.samefile(src, dst)
+ except OSError:
+ return False
+
+ # All other platforms: check for same pathname.
+ return (os.path.normcase(os.path.abspath(src)) ==
+ os.path.normcase(os.path.abspath(dst)))
+
+def copyfile(src, dst, *, follow_symlinks=True):
+ """Copy data from src to dst.
+
+ If follow_symlinks is not set and src is a symbolic link, a new
+ symlink will be created instead of copying the file it points to.
+
+ """
+ if _samefile(src, dst):
+ raise SameFileError("{!r} and {!r} are the same file".format(src, dst))
+
+ for fn in [src, dst]:
+ try:
+ st = os.stat(fn)
+ except OSError:
+ # File most likely does not exist
+ pass
+ else:
+ # XXX What about other special files? (sockets, devices...)
+ if stat.S_ISFIFO(st.st_mode):
+ raise SpecialFileError("`%s` is a named pipe" % fn)
+
+ if not follow_symlinks and os.path.islink(src):
+ os.symlink(os.readlink(src), dst)
+ else:
+ with open(src, 'rb') as fsrc:
+ with open(dst, 'wb') as fdst:
+ copyfileobj(fsrc, fdst)
+ return dst
+
+def copymode(src, dst, *, follow_symlinks=True):
+ """Copy mode bits from src to dst.
+
+ If follow_symlinks is not set, symlinks aren't followed if and only
+ if both `src` and `dst` are symlinks. If `lchmod` isn't available
+ (e.g. Linux) this method does nothing.
+
+ """
+ if not follow_symlinks and os.path.islink(src) and os.path.islink(dst):
+ if hasattr(os, 'lchmod'):
+ stat_func, chmod_func = os.lstat, os.lchmod
+ else:
+ return
+ elif hasattr(os, 'chmod'):
+ stat_func, chmod_func = os.stat, os.chmod
+ else:
+ return
+
+ st = stat_func(src)
+ chmod_func(dst, stat.S_IMODE(st.st_mode))
+
+if hasattr(os, 'listxattr'):
+ def _copyxattr(src, dst, *, follow_symlinks=True):
+ """Copy extended filesystem attributes from `src` to `dst`.
+
+ Overwrite existing attributes.
+
+ If `follow_symlinks` is false, symlinks won't be followed.
+
+ """
+
+ try:
+ names = os.listxattr(src, follow_symlinks=follow_symlinks)
+ except OSError as e:
+ if e.errno not in (errno.ENOTSUP, errno.ENODATA):
+ raise
+ return
+ for name in names:
+ try:
+ value = os.getxattr(src, name, follow_symlinks=follow_symlinks)
+ os.setxattr(dst, name, value, follow_symlinks=follow_symlinks)
+ except OSError as e:
+ if e.errno not in (errno.EPERM, errno.ENOTSUP, errno.ENODATA):
+ raise
+else:
+ def _copyxattr(*args, **kwargs):
+ pass
+
+def copystat(src, dst, *, follow_symlinks=True):
+ """Copy file metadata
+
+ Copy the permission bits, last access time, last modification time, and
+ flags from `src` to `dst`. On Linux, copystat() also copies the "extended
+ attributes" where possible. The file contents, owner, and group are
+ unaffected. `src` and `dst` are path names given as strings.
+
+ If the optional flag `follow_symlinks` is not set, symlinks aren't
+ followed if and only if both `src` and `dst` are symlinks.
+ """
+ def _nop(*args, ns=None, follow_symlinks=None):
+ pass
+
+ # follow symlinks (aka don't not follow symlinks)
+ follow = follow_symlinks or not (os.path.islink(src) and os.path.islink(dst))
+ if follow:
+ # use the real function if it exists
+ def lookup(name):
+ return getattr(os, name, _nop)
+ else:
+ # use the real function only if it exists
+ # *and* it supports follow_symlinks
+ def lookup(name):
+ fn = getattr(os, name, _nop)
+ if fn in os.supports_follow_symlinks:
+ return fn
+ return _nop
+
+ st = lookup("stat")(src, follow_symlinks=follow)
+ mode = stat.S_IMODE(st.st_mode)
+ lookup("utime")(dst, ns=(st.st_atime_ns, st.st_mtime_ns),
+ follow_symlinks=follow)
+ try:
+ lookup("chmod")(dst, mode, follow_symlinks=follow)
+ except NotImplementedError:
+ # if we got a NotImplementedError, it's because
+ # * follow_symlinks=False,
+ # * lchown() is unavailable, and
+ # * either
+ # * fchownat() is unavailable or
+ # * fchownat() doesn't implement AT_SYMLINK_NOFOLLOW.
+ # (it returned ENOSUP.)
+ # therefore we're out of options--we simply cannot chown the
+ # symlink. give up, suppress the error.
+ # (which is what shutil always did in this circumstance.)
+ pass
+ if hasattr(st, 'st_flags'):
+ try:
+ lookup("chflags")(dst, st.st_flags, follow_symlinks=follow)
+ except OSError as why:
+ for err in 'EOPNOTSUPP', 'ENOTSUP':
+ if hasattr(errno, err) and why.errno == getattr(errno, err):
+ break
+ else:
+ raise
+ _copyxattr(src, dst, follow_symlinks=follow)
+
+def copy(src, dst, *, follow_symlinks=True):
+ """Copy data and mode bits ("cp src dst"). Return the file's destination.
+
+ The destination may be a directory.
+
+ If follow_symlinks is false, symlinks won't be followed. This
+ resembles GNU's "cp -P src dst".
+
+ If source and destination are the same file, a SameFileError will be
+ raised.
+
+ """
+ if os.path.isdir(dst):
+ dst = os.path.join(dst, os.path.basename(src))
+ copyfile(src, dst, follow_symlinks=follow_symlinks)
+ copymode(src, dst, follow_symlinks=follow_symlinks)
+ return dst
+
+def copy2(src, dst, *, follow_symlinks=True):
+ """Copy data and metadata. Return the file's destination.
+
+ Metadata is copied with copystat(). Please see the copystat function
+ for more information.
+
+ The destination may be a directory.
+
+ If follow_symlinks is false, symlinks won't be followed. This
+ resembles GNU's "cp -P src dst".
+
+ """
+ if os.path.isdir(dst):
+ dst = os.path.join(dst, os.path.basename(src))
+ copyfile(src, dst, follow_symlinks=follow_symlinks)
+ copystat(src, dst, follow_symlinks=follow_symlinks)
+ return dst
+
+def ignore_patterns(*patterns):
+ """Function that can be used as copytree() ignore parameter.
+
+ Patterns is a sequence of glob-style patterns
+ that are used to exclude files"""
+ def _ignore_patterns(path, names):
+ ignored_names = []
+ for pattern in patterns:
+ ignored_names.extend(fnmatch.filter(names, pattern))
+ return set(ignored_names)
+ return _ignore_patterns
+
+def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
+ ignore_dangling_symlinks=False):
+ """Recursively copy a directory tree.
+
+ The destination directory must not already exist.
+ If exception(s) occur, an Error is raised with a list of reasons.
+
+ If the optional symlinks flag is true, symbolic links in the
+ source tree result in symbolic links in the destination tree; if
+ it is false, the contents of the files pointed to by symbolic
+ links are copied. If the file pointed by the symlink doesn't
+ exist, an exception will be added in the list of errors raised in
+ an Error exception at the end of the copy process.
+
+ You can set the optional ignore_dangling_symlinks flag to true if you
+ want to silence this exception. Notice that this has no effect on
+ platforms that don't support os.symlink.
+
+ The optional ignore argument is a callable. If given, it
+ is called with the `src` parameter, which is the directory
+ being visited by copytree(), and `names` which is the list of
+ `src` contents, as returned by os.listdir():
+
+ callable(src, names) -> ignored_names
+
+ Since copytree() is called recursively, the callable will be
+ called once for each directory that is copied. It returns a
+ list of names relative to the `src` directory that should
+ not be copied.
+
+ The optional copy_function argument is a callable that will be used
+ to copy each file. It will be called with the source path and the
+ destination path as arguments. By default, copy2() is used, but any
+ function that supports the same signature (like copy()) can be used.
+
+ """
+ names = os.listdir(src)
+ if ignore is not None:
+ ignored_names = ignore(src, names)
+ else:
+ ignored_names = set()
+
+ os.makedirs(dst)
+ errors = []
+ for name in names:
+ if name in ignored_names:
+ continue
+ srcname = os.path.join(src, name)
+ dstname = os.path.join(dst, name)
+ try:
+ if os.path.islink(srcname):
+ linkto = os.readlink(srcname)
+ if symlinks:
+ # We can't just leave it to `copy_function` because legacy
+ # code with a custom `copy_function` may rely on copytree
+ # doing the right thing.
+ os.symlink(linkto, dstname)
+ copystat(srcname, dstname, follow_symlinks=not symlinks)
+ else:
+ # ignore dangling symlink if the flag is on
+ if not os.path.exists(linkto) and ignore_dangling_symlinks:
+ continue
+ # otherwise let the copy occurs. copy2 will raise an error
+ if os.path.isdir(srcname):
+ copytree(srcname, dstname, symlinks, ignore,
+ copy_function)
+ else:
+ copy_function(srcname, dstname)
+ elif os.path.isdir(srcname):
+ copytree(srcname, dstname, symlinks, ignore, copy_function)
+ else:
+ # Will raise a SpecialFileError for unsupported file types
+ copy_function(srcname, dstname)
+ # catch the Error from the recursive copytree so that we can
+ # continue with other files
+ except Error as err:
+ errors.extend(err.args[0])
+ except OSError as why:
+ errors.append((srcname, dstname, str(why)))
+ try:
+ copystat(src, dst)
+ except OSError as why:
+ # Copying file access times may fail on Windows
+ if getattr(why, 'winerror', None) is None:
+ errors.append((src, dst, str(why)))
+ if errors:
+ raise Error(errors)
+ return dst
+
+# version vulnerable to race conditions
+def _rmtree_unsafe(path, onerror):
+ try:
+ if os.path.islink(path):
+ # symlinks to directories are forbidden, see bug #1669
+ raise OSError("Cannot call rmtree on a symbolic link")
+ except OSError:
+ onerror(os.path.islink, path, sys.exc_info())
+ # can't continue even if onerror hook returns
+ return
+ names = []
+ try:
+ names = os.listdir(path)
+ except OSError:
+ onerror(os.listdir, path, sys.exc_info())
+ for name in names:
+ fullname = os.path.join(path, name)
+ try:
+ mode = os.lstat(fullname).st_mode
+ except OSError:
+ mode = 0
+ if stat.S_ISDIR(mode):
+ _rmtree_unsafe(fullname, onerror)
+ else:
+ try:
+ os.unlink(fullname)
+ except OSError:
+ onerror(os.unlink, fullname, sys.exc_info())
+ try:
+
This message has been truncated.

Join devel@edk2.groups.io to automatically receive all group messages.